java实现二叉树的创建及5种遍历

Java实现的数组创建二叉树以及递归先序遍历,递归中序遍历,递归后序遍历,非递归前序遍历,非递归中序遍历,非递归后序遍历,深度优先遍历,广度优先遍历8种遍历方式:

  1. package myTest;  
  2.   
  3. import java.util.ArrayList;  
  4. import java.util.LinkedList;  
  5. import java.util.List;  
  6. import java.util.Stack;  
  7.   
  8. public class myClass {  
  9.       
  10.     public static void main(String[] args) {  
  11.         // TODO Auto-generated method stub  
  12.         myClass tree = new myClass();  
  13.         int[] datas = new int[]{1,2,3,4,5,6,7,8,9};  
  14.         List<Node> nodelist = new LinkedList<>();  
  15.         tree.creatBinaryTree(datas, nodelist);  
  16.         Node root = nodelist.get(0);  
  17.         System.out.println("递归先序遍历:");  
  18.         tree.preOrderTraversal(root);  
  19.         System.out.println();  
  20.         System.out.println("非递归先序遍历:");  
  21.         tree.preOrderTraversalbyLoop(root);  
  22.         System.out.println();  
  23.         System.out.println("递归中序遍历:");  
  24.         tree.inOrderTraversal(root);  
  25.         System.out.println();  
  26.         System.out.println("非递归中序遍历:");  
  27.         tree.inOrderTraversalbyLoop(root);  
  28.         System.out.println();  
  29.         System.out.println("递归后序遍历:");  
  30.         tree.postOrderTraversal(root);  
  31.         System.out.println();  
  32.         System.out.println("非递归后序遍历:");  
  33.         tree.postOrderTraversalbyLoop(root);  
  34.         System.out.println();  
  35.         System.out.println("广度优先遍历:");  
  36.         tree.bfs(root);  
  37.         System.out.println();  
  38.         System.out.println("深度优先遍历:");  
  39.         List<List<Integer>> rst = new ArrayList<>();  
  40.         List<Integer> list = new ArrayList<>();  
  41.         tree.dfs(root,rst,list);  
  42.         System.out.println(rst);  
  43.     }  
  44.     /** 
  45.      *  
  46.      * @param datas 实现二叉树各节点值的数组 
  47.      * @param nodelist 二叉树list 
  48.      */  
  49.     private void creatBinaryTree(int[] datas,List<Node> nodelist){  
  50.         //将数组变成node节点  
  51.         for(int nodeindex=0;nodeindex<datas.length;nodeindex++){  
  52.             Node node = new Node(datas[nodeindex]);  
  53.             nodelist.add(node);  
  54.         }  
  55.         //给所有父节点设定子节点  
  56.         for(int index=0;index<nodelist.size()/2-1;index++){  
  57.             //编号为n的节点他的左子节点编号为2*n 右子节点编号为2*n+1 但是因为list从0开始编号,所以还要+1  
  58.             //这里父节点有1(2,3),2(4,5),3(6,7),4(8,9) 但是最后一个父节点有可能没有右子节点 需要单独处理  
  59.             nodelist.get(index).setLeft(nodelist.get(index*2+1));   
  60.             nodelist.get(index).setRight(nodelist.get(index*2+2));  
  61.         }  
  62.         //单独处理最后一个父节点  因为它有可能没有右子节点  
  63.         int index = nodelist.size()/2-1;  
  64.         nodelist.get(index).setLeft(nodelist.get(index*2+1)); //先设置左子节点  
  65.         if(nodelist.size() % 2 == 1){ //如果有奇数个节点,最后一个父节点才有右子节点  
  66.             nodelist.get(index).setRight(nodelist.get(index*2+2));  
  67.         }  
  68.     }  
  69.     /** 
  70.      * 遍历当前节点的值 
  71.      * @param nodelist 
  72.      * @param node 
  73.      */  
  74.     public void checkCurrentNode(Node node){  
  75.         System.out.print(node.getVar()+" ");  
  76.     }  
  77.     /** 
  78.      * 先序遍历二叉树 
  79.      * @param root 二叉树根节点 
  80.      */  
  81.     public void preOrderTraversal(Node node){  
  82.         if (node == null)  //很重要,必须加上 当遇到叶子节点用来停止向下遍历  
  83.             return;    
  84.         checkCurrentNode(node);  
  85.         preOrderTraversal(node.getLeft());  
  86.         preOrderTraversal(node.getRight());  
  87.     }  
  88.     /** 
  89.      * 中序遍历二叉树 
  90.      * @param root 根节点 
  91.      */  
  92.     public void inOrderTraversal(Node node){  
  93.         if (node == null)  //很重要,必须加上  
  94.             return;    
  95.         inOrderTraversal(node.getLeft());  
  96.         checkCurrentNode(node);  
  97.         inOrderTraversal(node.getRight());  
  98.     }  
  99.     /** 
  100.      * 后序遍历二叉树 
  101.      * @param root 根节点 
  102.      */  
  103.     public void postOrderTraversal(Node node){  
  104.         if (node == null)  //很重要,必须加上  
  105.             return;    
  106.         postOrderTraversal(node.getLeft());  
  107.         postOrderTraversal(node.getRight());  
  108.         checkCurrentNode(node);  
  109.     }  
  110.       
  111.     /** 
  112.      * 非递归前序遍历 
  113.      * @param node 
  114.      */  
  115.     public void preOrderTraversalbyLoop(Node node){  
  116.         Stack<Node> stack = new Stack();  
  117.         Node p = node;  
  118.         while(p!=null || !stack.isEmpty()){  
  119.             while(p!=null){ //当p不为空时,就读取p的值,并不断更新p为其左子节点,即不断读取左子节点  
  120.                 checkCurrentNode(p);  
  121.                 stack.push(p); //将p入栈  
  122.                 p = p.getLeft();  
  123.             }  
  124.             if(!stack.isEmpty()){  
  125.                 p = stack.pop();  
  126.                 p = p.getRight();  
  127.             }  
  128.         }  
  129.     }  
  130.     /** 
  131.      * 非递归中序遍历 
  132.      * @param node 
  133.      */  
  134.     public void inOrderTraversalbyLoop(Node node){  
  135.         Stack<Node> stack = new Stack();  
  136.         Node p = node;  
  137.         while(p!=null || !stack.isEmpty()){  
  138.             while(p!=null){  
  139.                 stack.push(p);  
  140.                 p = p.getLeft();  
  141.             }  
  142.             if(!stack.isEmpty()){     
  143.                 p = stack.pop();  
  144.                 checkCurrentNode(p);  
  145.                 p = p.getRight();  
  146.             }  
  147.         }  
  148.     }  
  149.     /** 
  150.      * 非递归后序遍历 
  151.      * @param node 
  152.      */  
  153.     public void postOrderTraversalbyLoop(Node node){  
  154.         Stack<Node> stack = new Stack<>();  
  155.         Node p = node,prev = node;  
  156.         while(p!=null || !stack.isEmpty()){  
  157.             while(p!=null){  
  158.                 stack.push(p);  
  159.                 p = p.getLeft();  
  160.             }  
  161.             if(!stack.isEmpty()){  
  162.                 Node temp = stack.peek().getRight();  
  163.                 if(temp == null||temp == prev){  
  164.                     p = stack.pop();  
  165.                     checkCurrentNode(p);  
  166.                     prev = p;  
  167.                     p = null;  
  168.                 }else{  
  169.                     p = temp;  
  170.                 }     
  171.             }  
  172.         }  
  173.     }  
  174.       
  175.     /** 
  176.      * 广度优先遍历(从上到下遍历二叉树) 
  177.      * @param root 
  178.      */  
  179.     public void bfs(Node root){  
  180.           if(root == nullreturn;  
  181.           LinkedList<Node> queue = new LinkedList<Node>();  
  182.           queue.offer(root); //首先将根节点存入队列  
  183.           //当队列里有值时,每次取出队首的node打印,打印之后判断node是否有子节点,若有,则将子节点加入队列  
  184.           while(queue.size() > 0){   
  185.             Node node = queue.peek();  
  186.             queue.poll(); //取出队首元素并打印  
  187.             System.out.print(node.var+" ");  
  188.             if(node.left != null){ //如果有左子节点,则将其存入队列  
  189.               queue.offer(node.left);  
  190.             }  
  191.             if(node.right != null){ //如果有右子节点,则将其存入队列  
  192.               queue.offer(node.right);  
  193.             }  
  194.           }  
  195.     }  
  196.     /** 
  197.      * 深度优先遍历 
  198.      * @param node 
  199.      * @param rst 
  200.      * @param list 
  201.      */  
  202.     public void dfs(Node node,List<List<Integer>> rst,List<Integer> list){  
  203.         if(node == nullreturn;  
  204.         if(node.left == null && node.right == null){  
  205.             list.add(node.var);  
  206.             /* 这里将list存入rst中时,不能直接将list存入,而是通过新建一个list来实现, 
  207.              * 因为如果直接用list的话,后面remove的时候也会将其最后一个存的节点删掉*/  
  208.             rst.add(new ArrayList<>(list));  
  209.             list.remove(list.size()-1);  
  210.         }  
  211.         list.add(node.var);  
  212.         dfs(node.left,rst,list);  
  213.         dfs(node.right,rst,list);  
  214.         list.remove(list.size()-1);  
  215.     }  
  216.     /** 
  217.      * 节点类 
  218.      * var 节点值 
  219.      * left 节点左子节点 
  220.      * right 右子节点 
  221.      */   
  222.     class Node{  
  223.         int var;  
  224.         Node left;  
  225.         Node right;  
  226.         public Node(int var){  
  227.             this.var = var;  
  228.             this.left = null;  
  229.             this.right = null;  
  230.         }  
  231.         public void setLeft(Node left) {  
  232.             this.left = left;  
  233.         }  
  234.         public void setRight(Node right) {  
  235.             this.right = right;  
  236.         }  
  237.         public int getVar() {  
  238.             return var;  
  239.         }  
  240.         public void setVar(int var) {  
  241.             this.var = var;  
  242.         }  
  243.         public Node getLeft() {  
  244.             return left;  
  245.         }  
  246.         public Node getRight() {  
  247.             return right;  
  248.         }  
  249.           
  250.     }  
  251.   
  252. }  

运行结果:

[java]  view plain  copy
  在CODE上查看代码片 派生到我的代码片
  1. 递归先序遍历:  
  2. 1 2 4 8 9 5 3 6 7   
  3. 非递归先序遍历:  
  4. 1 2 4 8 9 5 3 6 7   
  5. 递归中序遍历:  
  6. 8 4 9 2 5 1 6 3 7   
  7. 非递归中序遍历:  
  8. 8 4 9 2 5 1 6 3 7   
  9. 递归后序遍历:  
  10. 8 9 4 5 2 6 7 3 1   
  11. 非递归后序遍历:  
  12. 8 9 4 5 2 6 7 3 1   
  13. 广度优先遍历:  
  14. 1 2 3 4 5 6 7 8 9   
  15. 深度优先遍历:  
  16. [[1248], [1249], [125], [136], [137]]  

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值