溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

利用java如何實現創建并遍歷二叉樹

發布時間:2020-11-16 16:27:16 來源:億速云 閱讀:376 作者:Leah 欄目:編程語言

利用java如何實現創建并遍歷二叉樹?針對這個問題,這篇文章詳細介紹了相對應的分析和解答,希望可以幫助更多想解決這個問題的小伙伴找到更簡單易行的方法。

用java實現的數組創建二叉樹以及遞歸先序遍歷,遞歸中序遍歷,遞歸后序遍歷,非遞歸前序遍歷,非遞歸中序遍歷,非遞歸后序遍歷,深度優先遍歷,廣度優先遍歷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("廣度優先遍歷:");
 tree.bfs(root);
 System.out.println();
 System.out.println("深度優先遍歷:");
 List<List<Integer>> rst = new ArrayList<>();
 List<Integer> list = new ArrayList<>();
 tree.dfs(root,rst,list);
 System.out.println(rst);
 }
 /**
 * 
 * @param datas 實現二叉樹各節點值的數組
 * @param nodelist 二叉樹list
 */
 private void creatBinaryTree(int[] datas,List<Node> nodelist){
 //將數組變成node節點
 for(int nodeindex=0;nodeindex<datas.length;nodeindex++){
  Node node = new Node(datas[nodeindex]);
  nodelist.add(node);
 }
 //給所有父節點設定子節點
 for(int index=0;index<nodelist.size()/2-1;index++){
  //編號為n的節點他的左子節點編號為2*n 右子節點編號為2*n+1 但是因為list從0開始編號,所以還要+1
  //這里父節點有1(2,3),2(4,5),3(6,7),4(8,9) 但是最后一個父節點有可能沒有右子節點 需要單獨處理
  nodelist.get(index).setLeft(nodelist.get(index*2+1)); 
  nodelist.get(index).setRight(nodelist.get(index*2+2));
 }
 //單獨處理最后一個父節點 因為它有可能沒有右子節點
 int index = nodelist.size()/2-1;
 nodelist.get(index).setLeft(nodelist.get(index*2+1)); //先設置左子節點
 if(nodelist.size() % 2 == 1){ //如果有奇數個節點,最后一個父節點才有右子節點
  nodelist.get(index).setRight(nodelist.get(index*2+2));
 }
 }
 /**
 * 遍歷當前節點的值
 * @param nodelist
 * @param node
 */
 public void checkCurrentNode(Node node){
 System.out.print(node.getVar()+" ");
 }
 /**
 * 先序遍歷二叉樹
 * @param root 二叉樹根節點
 */
 public void preOrderTraversal(Node node){
 if (node == null) //很重要,必須加上 當遇到葉子節點用來停止向下遍歷
      return; 
 checkCurrentNode(node);
 preOrderTraversal(node.getLeft());
 preOrderTraversal(node.getRight());
 }
 /**
 * 中序遍歷二叉樹
 * @param root 根節點
 */
 public void inOrderTraversal(Node node){
 if (node == null) //很重要,必須加上
      return; 
 inOrderTraversal(node.getLeft());
 checkCurrentNode(node);
 inOrderTraversal(node.getRight());
 }
 /**
 * 后序遍歷二叉樹
 * @param root 根節點
 */
 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){ //當p不為空時,就讀取p的值,并不斷更新p為其左子節點,即不斷讀取左子節點
  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;
  } 
  }
 }
 }
 
 /**
 * 廣度優先遍歷(從上到下遍歷二叉樹)
 * @param root
 */
 public void bfs(Node root){
  if(root == null) return;
  LinkedList<Node> queue = new LinkedList<Node>();
  queue.offer(root); //首先將根節點存入隊列
  //當隊列里有值時,每次取出隊首的node打印,打印之后判斷node是否有子節點,若有,則將子節點加入隊列
  while(queue.size() > 0){ 
  Node node = queue.peek();
   queue.poll(); //取出隊首元素并打印
   System.out.print(node.var+" ");
   if(node.left != null){ //如果有左子節點,則將其存入隊列
    queue.offer(node.left);
   }
   if(node.right != null){ //如果有右子節點,則將其存入隊列
    queue.offer(node.right);
   }
  }
 }
 /**
 * 深度優先遍歷
 * @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中時,不能直接將list存入,而是通過新建一個list來實現,
  * 因為如果直接用list的話,后面remove的時候也會將其最后一個存的節點刪掉*/
  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);
 }
 /**
 * 節點類
 * var 節點值
 * left 節點左子節點
 * right 右子節點
 */ 
 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;
 }
 
 }

}

運行結果:

遞歸先序遍歷:
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

廣度優先遍歷:
1 2 3 4 5 6 7 8 9

深度優先遍歷:
[[1, 2, 4, 8], [1, 2, 4, 9], [1, 2, 5], [1, 3, 6], [1, 3, 7]]

關于利用java如何實現創建并遍歷二叉樹問題的解答就分享到這里了,希望以上內容可以對大家有一定的幫助,如果你還有很多疑惑沒有解開,可以關注億速云行業資訊頻道了解更多相關知識。

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

亚洲午夜精品一区二区_中文无码日韩欧免_久久香蕉精品视频_欧美主播一区二区三区美女