最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

java實(shí)現(xiàn)二叉樹(shù)的創(chuàng)建及5種遍歷方法(總結(jié))

 更新時(shí)間:2017年04月10日 09:49:40   投稿:jingxian  
下面小編就為大家?guī)?lái)一篇java實(shí)現(xiàn)二叉樹(shù)的創(chuàng)建及5種遍歷方法(總結(jié))。小編覺(jué)得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧

用java實(shí)現(xiàn)的數(shù)組創(chuàng)建二叉樹(shù)以及遞歸先序遍歷,遞歸中序遍歷,遞歸后序遍歷,非遞歸前序遍歷,非遞歸中序遍歷,非遞歸后序遍歷,深度優(yōu)先遍歷,廣度優(yōu)先遍歷8種遍歷方式:

package myTest;

import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;
import java.util.Stack;

public class myClass {
 
 public static void main(String[] args) {
 // TODO Auto-generated method stub
 myClass tree = new myClass();
 int[] datas = new int[]{1,2,3,4,5,6,7,8,9};
 List<Node> nodelist = new LinkedList<>();
 tree.creatBinaryTree(datas, nodelist);
 Node root = nodelist.get(0);
 System.out.println("遞歸先序遍歷:");
 tree.preOrderTraversal(root);
 System.out.println();
 System.out.println("非遞歸先序遍歷:");
 tree.preOrderTraversalbyLoop(root);
 System.out.println();
 System.out.println("遞歸中序遍歷:");
 tree.inOrderTraversal(root);
 System.out.println();
 System.out.println("非遞歸中序遍歷:");
 tree.inOrderTraversalbyLoop(root);
 System.out.println();
 System.out.println("遞歸后序遍歷:");
 tree.postOrderTraversal(root);
 System.out.println();
 System.out.println("非遞歸后序遍歷:");
 tree.postOrderTraversalbyLoop(root);
 System.out.println();
 System.out.println("廣度優(yōu)先遍歷:");
 tree.bfs(root);
 System.out.println();
 System.out.println("深度優(yōu)先遍歷:");
 List<List<Integer>> rst = new ArrayList<>();
 List<Integer> list = new ArrayList<>();
 tree.dfs(root,rst,list);
 System.out.println(rst);
 }
 /**
 * 
 * @param datas 實(shí)現(xiàn)二叉樹(shù)各節(jié)點(diǎn)值的數(shù)組
 * @param nodelist 二叉樹(shù)list
 */
 private void creatBinaryTree(int[] datas,List<Node> nodelist){
 //將數(shù)組變成node節(jié)點(diǎn)
 for(int nodeindex=0;nodeindex<datas.length;nodeindex++){
  Node node = new Node(datas[nodeindex]);
  nodelist.add(node);
 }
 //給所有父節(jié)點(diǎn)設(shè)定子節(jié)點(diǎn)
 for(int index=0;index<nodelist.size()/2-1;index++){
  //編號(hào)為n的節(jié)點(diǎn)他的左子節(jié)點(diǎn)編號(hào)為2*n 右子節(jié)點(diǎn)編號(hào)為2*n+1 但是因?yàn)閘ist從0開(kāi)始編號(hào),所以還要+1
  //這里父節(jié)點(diǎn)有1(2,3),2(4,5),3(6,7),4(8,9) 但是最后一個(gè)父節(jié)點(diǎn)有可能沒(méi)有右子節(jié)點(diǎn) 需要單獨(dú)處理
  nodelist.get(index).setLeft(nodelist.get(index*2+1)); 
  nodelist.get(index).setRight(nodelist.get(index*2+2));
 }
 //單獨(dú)處理最后一個(gè)父節(jié)點(diǎn) 因?yàn)樗锌赡軟](méi)有右子節(jié)點(diǎn)
 int index = nodelist.size()/2-1;
 nodelist.get(index).setLeft(nodelist.get(index*2+1)); //先設(shè)置左子節(jié)點(diǎn)
 if(nodelist.size() % 2 == 1){ //如果有奇數(shù)個(gè)節(jié)點(diǎn),最后一個(gè)父節(jié)點(diǎn)才有右子節(jié)點(diǎn)
  nodelist.get(index).setRight(nodelist.get(index*2+2));
 }
 }
 /**
 * 遍歷當(dāng)前節(jié)點(diǎn)的值
 * @param nodelist
 * @param node
 */
 public void checkCurrentNode(Node node){
 System.out.print(node.getVar()+" ");
 }
 /**
 * 先序遍歷二叉樹(shù)
 * @param root 二叉樹(shù)根節(jié)點(diǎn)
 */
 public void preOrderTraversal(Node node){
 if (node == null) //很重要,必須加上 當(dāng)遇到葉子節(jié)點(diǎn)用來(lái)停止向下遍歷
      return; 
 checkCurrentNode(node);
 preOrderTraversal(node.getLeft());
 preOrderTraversal(node.getRight());
 }
 /**
 * 中序遍歷二叉樹(shù)
 * @param root 根節(jié)點(diǎn)
 */
 public void inOrderTraversal(Node node){
 if (node == null) //很重要,必須加上
      return; 
 inOrderTraversal(node.getLeft());
 checkCurrentNode(node);
 inOrderTraversal(node.getRight());
 }
 /**
 * 后序遍歷二叉樹(shù)
 * @param root 根節(jié)點(diǎn)
 */
 public void postOrderTraversal(Node node){
 if (node == null) //很重要,必須加上
      return; 
 postOrderTraversal(node.getLeft());
 postOrderTraversal(node.getRight());
 checkCurrentNode(node);
 }
 
 /**
 * 非遞歸前序遍歷
 * @param node
 */
 public void preOrderTraversalbyLoop(Node node){
 Stack<Node> stack = new Stack();
 Node p = node;
 while(p!=null || !stack.isEmpty()){
  while(p!=null){ //當(dāng)p不為空時(shí),就讀取p的值,并不斷更新p為其左子節(jié)點(diǎn),即不斷讀取左子節(jié)點(diǎn)
  checkCurrentNode(p);
  stack.push(p); //將p入棧
  p = p.getLeft();
  }
  if(!stack.isEmpty()){
  p = stack.pop();
  p = p.getRight();
  }
 }
 }
 /**
 * 非遞歸中序遍歷
 * @param node
 */
 public void inOrderTraversalbyLoop(Node node){
 Stack<Node> stack = new Stack();
 Node p = node;
 while(p!=null || !stack.isEmpty()){
  while(p!=null){
  stack.push(p);
  p = p.getLeft();
  }
  if(!stack.isEmpty()){ 
  p = stack.pop();
  checkCurrentNode(p);
  p = p.getRight();
  }
 }
 }
 /**
 * 非遞歸后序遍歷
 * @param node
 */
 public void postOrderTraversalbyLoop(Node node){
 Stack<Node> stack = new Stack<>();
 Node p = node,prev = node;
 while(p!=null || !stack.isEmpty()){
  while(p!=null){
  stack.push(p);
  p = p.getLeft();
  }
  if(!stack.isEmpty()){
  Node temp = stack.peek().getRight();
  if(temp == null||temp == prev){
   p = stack.pop();
   checkCurrentNode(p);
   prev = p;
   p = null;
  }else{
   p = temp;
  } 
  }
 }
 }
 
 /**
 * 廣度優(yōu)先遍歷(從上到下遍歷二叉樹(shù))
 * @param root
 */
 public void bfs(Node root){
  if(root == null) return;
  LinkedList<Node> queue = new LinkedList<Node>();
  queue.offer(root); //首先將根節(jié)點(diǎn)存入隊(duì)列
  //當(dāng)隊(duì)列里有值時(shí),每次取出隊(duì)首的node打印,打印之后判斷node是否有子節(jié)點(diǎn),若有,則將子節(jié)點(diǎn)加入隊(duì)列
  while(queue.size() > 0){ 
  Node node = queue.peek();
   queue.poll(); //取出隊(duì)首元素并打印
   System.out.print(node.var+" ");
   if(node.left != null){ //如果有左子節(jié)點(diǎn),則將其存入隊(duì)列
    queue.offer(node.left);
   }
   if(node.right != null){ //如果有右子節(jié)點(diǎn),則將其存入隊(duì)列
    queue.offer(node.right);
   }
  }
 }
 /**
 * 深度優(yōu)先遍歷
 * @param node
 * @param rst
 * @param list
 */
 public void dfs(Node node,List<List<Integer>> rst,List<Integer> list){
 if(node == null) return;
 if(node.left == null && node.right == null){
  list.add(node.var);
  /* 這里將list存入rst中時(shí),不能直接將list存入,而是通過(guò)新建一個(gè)list來(lái)實(shí)現(xiàn),
  * 因?yàn)槿绻苯佑胠ist的話,后面remove的時(shí)候也會(huì)將其最后一個(gè)存的節(jié)點(diǎn)刪掉*/
  rst.add(new ArrayList<>(list));
  list.remove(list.size()-1);
 }
 list.add(node.var);
 dfs(node.left,rst,list);
 dfs(node.right,rst,list);
 list.remove(list.size()-1);
 }
 /**
 * 節(jié)點(diǎn)類
 * var 節(jié)點(diǎn)值
 * left 節(jié)點(diǎn)左子節(jié)點(diǎn)
 * right 右子節(jié)點(diǎn)
 */ 
 class Node{
 int var;
 Node left;
 Node right;
 public Node(int var){
  this.var = var;
  this.left = null;
  this.right = null;
 }
 public void setLeft(Node left) {
  this.left = left;
 }
 public void setRight(Node right) {
  this.right = right;
 }
 public int getVar() {
  return var;
 }
 public void setVar(int var) {
  this.var = var;
 }
 public Node getLeft() {
  return left;
 }
 public Node getRight() {
  return right;
 }
 
 }

}

運(yùn)行結(jié)果:

遞歸先序遍歷:
1 2 4 8 9 5 3 6 7

非遞歸先序遍歷:
1 2 4 8 9 5 3 6 7

遞歸中序遍歷:
8 4 9 2 5 1 6 3 7

非遞歸中序遍歷:
8 4 9 2 5 1 6 3 7

遞歸后序遍歷:
8 9 4 5 2 6 7 3 1

非遞歸后序遍歷:
8 9 4 5 2 6 7 3 1

廣度優(yōu)先遍歷:
1 2 3 4 5 6 7 8 9

深度優(yōu)先遍歷:
[[1, 2, 4, 8], [1, 2, 4, 9], [1, 2, 5], [1, 3, 6], [1, 3, 7]]

以上這篇java實(shí)現(xiàn)二叉樹(shù)的創(chuàng)建及5種遍歷方法(總結(jié))就是小編分享給大家的全部?jī)?nèi)容了,希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。

相關(guān)文章

  • Map集合的四種遍歷方式代碼示例

    Map集合的四種遍歷方式代碼示例

    這篇文章主要介紹了Map集合的四種遍歷方式代碼示例,具有一定參考價(jià)值,需要的朋友可以了解下。
    2017-10-10
  • SpringBoot2零基礎(chǔ)到精通之自動(dòng)配置底層分析及小技巧

    SpringBoot2零基礎(chǔ)到精通之自動(dòng)配置底層分析及小技巧

    SpringBoot是一種整合Spring技術(shù)棧的方式(或者說(shuō)是框架),同時(shí)也是簡(jiǎn)化Spring的一種快速開(kāi)發(fā)的腳手架,本篇讓我們一起學(xué)習(xí)自動(dòng)配置的底層分析與一些開(kāi)發(fā)中的小技巧
    2022-03-03
  • mybatis時(shí)間范圍查詢代碼示例

    mybatis時(shí)間范圍查詢代碼示例

    這篇文章主要給大家介紹了關(guān)于mybatis時(shí)間范圍查詢的相關(guān)資料,在項(xiàng)?中避免不了要?到時(shí)間范圍查詢,文中通過(guò)代碼示例介紹的非常詳細(xì),需要的朋友可以參考下
    2023-08-08
  • SpringMVC的概念以及快速入門示例

    SpringMVC的概念以及快速入門示例

    這篇文章主要介紹了SpringMVC的概念以及快速入門示例,SpringMVC 已經(jīng)成為目前最主流的MVC框架之一,它通過(guò)一套注解,讓一個(gè)簡(jiǎn)單的 Java 類成為處理請(qǐng)求的控制器,而無(wú)須實(shí)現(xiàn)任何接口,需要的朋友可以參考下
    2023-05-05
  • 一文帶你了解SpringBoot中常用注解的原理和使用

    一文帶你了解SpringBoot中常用注解的原理和使用

    這篇文章主要介紹了一文帶你了解SpringBoot中常用注解的原理和使用
    2022-11-11
  • java8新特性-lambda表達(dá)式入門學(xué)習(xí)心得

    java8新特性-lambda表達(dá)式入門學(xué)習(xí)心得

    這篇文章主要介紹了java8新特性-lambda表達(dá)式入門學(xué)習(xí)心得,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2023-03-03
  • 教你怎么用IDEA快速生成注釋文檔

    教你怎么用IDEA快速生成注釋文檔

    這篇文章主要介紹了教你怎么用IDEA快速生成注釋文檔,文中有非常詳細(xì)的代碼示例,對(duì)正在學(xué)習(xí)IDEA操作的小伙伴們有很好地幫助,需要的朋友可以參考下
    2021-05-05
  • SpringBoot整合Mybatis-plus實(shí)現(xiàn)多級(jí)評(píng)論功能

    SpringBoot整合Mybatis-plus實(shí)現(xiàn)多級(jí)評(píng)論功能

    本文介紹了如何使用SpringBoot整合Mybatis-plus實(shí)現(xiàn)多級(jí)評(píng)論功能,同時(shí)提供了數(shù)據(jù)庫(kù)的設(shè)計(jì)和詳細(xì)的后端代碼,前端界面使用的Vue2,本文通過(guò)實(shí)例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友參考下吧
    2023-05-05
  • Hadoop源碼分析五hdfs架構(gòu)原理剖析

    Hadoop源碼分析五hdfs架構(gòu)原理剖析

    本篇是Hadoop源碼分析系列文章第五篇,主要介紹Hadoop的hdfs架構(gòu)原理剖析,后續(xù)本系列文章會(huì)持續(xù)更新,有需要的朋友可以借鑒參考下
    2021-09-09
  • Java實(shí)現(xiàn)手寫(xiě)線程池實(shí)例并測(cè)試詳解

    Java實(shí)現(xiàn)手寫(xiě)線程池實(shí)例并測(cè)試詳解

    這篇文章主要來(lái)模擬一下線程池和工作隊(duì)列的流程,以及編寫(xiě)代碼和測(cè)試類進(jìn)行測(cè)試。文中的示例代碼講解詳細(xì),感興趣的小伙伴可以了解一下
    2023-02-02

最新評(píng)論

尚义县| 赣榆县| 舞阳县| 邯郸市| 民权县| 周宁县| 巴东县| 霞浦县| 甘南县| 磴口县| 渭南市| 边坝县| 东安县| 胶州市| 榆树市| 扶风县| 翁源县| 阿拉善右旗| 衡山县| 平阳县| 黎城县| 华阴市| 汪清县| 思南县| 凉山| 那坡县| 龙岩市| 宁强县| 宜春市| 洛川县| 塘沽区| 英德市| 保亭| 辽阳市| 桃江县| 格尔木市| 襄城县| 凤山县| 汉中市| 体育| 文水县|