二叉樹的遍歷(遞迴與非遞迴版本)
阿新 • • 發佈:2018-12-31
最近在寫關於二叉樹方面的題目的時候,總是會用到二叉樹的各種遍歷,所以在這裡將自己寫的各種遍歷,都記錄下來.
遞迴部分:
首先二叉樹的遞迴程式碼是比較簡單的,而且前序,中序和後序遍歷程式碼幾乎一樣, 只是列印節點值的輸出語句的位置不一樣.
可以遞迴部分,對於二叉樹中節點的遍歷順序是一樣的, 都是先遍歷當前節點,然後遍歷當前節點的左子樹,然後是右子樹, 然後在遍歷節點的過程, 選擇輸出的節點值的時機.
非遞迴部分:
其實思想還是參考遞迴部分, 只是將遞迴遍歷節點部分, 變成了使用棧來存放遍歷的節點, 然後選擇列印節點的值的時機
以下是程式碼部分
import java.util.LinkedList; import java.util.Queue; import java.util.Stack; /** * author: zzw5005 * date: 2018/11/24 9:57 */ public class TraversalBST { //遞迴版本的二叉樹遍歷 public static void preOrder(TreeNode root){ if(root == null){ return; } System.out.print(root.val + " "); preOrder(root.left); preOrder(root.right); } public static void inOrder(TreeNode root){ if(root == null){ return; } inOrder(root.left); System.out.print(root.val + " "); inOrder(root.right); } public static void posOrder(TreeNode root){ if(root == null){ return; } posOrder(root.left); posOrder(root.right); System.out.print(root.val + " "); } //非遞迴版本的二叉樹遍歷 public static void preOrder1(TreeNode root){ Stack<TreeNode> stack = new Stack<>(); while(!stack.isEmpty() || root != null){ while(root != null){ System.out.print(root.val + " "); stack.push(root); root = root.left; } if(!stack.isEmpty()){ root = stack.pop(); root = root.right; } } } public static void inOrder1(TreeNode root){ Stack<TreeNode> stack = new Stack<>(); while(!stack.isEmpty() || root != null){ while(root != null){ stack.push(root); root = root.left; } if(!stack.isEmpty()){ root = stack.pop(); System.out.print(root.val + " "); root = root.right; } } } public static void posOrder1(TreeNode root){ Stack<TreeNode> stack1 = new Stack<>(); Stack<Integer> stack2 = new Stack<>(); while(!stack1.isEmpty() || root != null){ while(root != null){ stack1.push(root); stack2.push(0); root = root.left; } while(!stack1.isEmpty() && stack2.peek() == 1){ stack2.pop(); System.out.print(stack1.pop().val + " "); } if(!stack1.isEmpty()){ stack2.pop(); stack2.push(1); root = stack1.peek(); root = root.right; } } } public static void levOrder(TreeNode root){ if(root == null){ return; } Queue<TreeNode> queue = new LinkedList<>(); queue.add(root); while(!queue.isEmpty()){ root = queue.poll(); System.out.print(root.val + " "); if(root.left != null){ queue.add(root.left); } if(root.right != null){ queue.add(root.right); } } } public static class TreeNode { int val = 0; TreeNode left = null; TreeNode right = null; public TreeNode(int val) { this.val = val; } } public static void main(String[] args) { //樹 TreeNode root = new TreeNode(8); root.left = new TreeNode(6); root.right = new TreeNode(10); //root.left = new TreeNode(6); root.left.left = new TreeNode(5); root.left.right = new TreeNode(7); //root.left.right = new TreeNode(10); root.right.left = new TreeNode(9); root.right.right = new TreeNode(11); System.out.println("遞迴版本的二叉樹遍歷 : "); System.out.print("preOrder : "); preOrder(root); System.out.println(); System.out.print("inOrder : "); inOrder(root); System.out.println(); System.out.print("posOrder : "); posOrder(root); System.out.println("\n"); System.out.println("非遞迴版本的二叉樹遍歷 : "); System.out.print("preOrder1 : "); preOrder1(root); System.out.println(); System.out.print("inOrder1 : "); inOrder1(root); System.out.println(); System.out.print("posOrder1 : "); posOrder1(root); System.out.println(); System.out.print("levOrder : "); levOrder(root); System.out.println(); } }
輸出的結果
遞迴版本的二叉樹遍歷 :
preOrder : 8 6 5 7 10 9 11
inOrder : 5 6 7 8 9 10 11
posOrder : 5 7 6 9 11 10 8
非遞迴版本的二叉樹遍歷 :
preOrder1 : 8 6 5 7 10 9 11
inOrder1 : 5 6 7 8 9 10 11
posOrder1 : 5 7 6 9 11 10 8
levOrder : 8 6 10 5 7 9 11