Java二叉樹的四種遍歷(遞歸與非遞歸)
一、先序遍歷與後序遍歷
先序遍歷根節點,再遍歷左子樹,再遍歷右子樹。
後序遍歷先遍歷左子樹,再遍歷右子樹,再遍歷根節點。
先序遍歷遞歸實現:
public static void preOrderByRecursion(TreeNode root) { // 打印節點值 System.out.println(root.value); preOrder(root.left); preOrder(root.right); }
先序遍歷的非遞歸實現:
非遞歸實現需要借助棧這樣一個數據結構,實際上遞歸實現也是依靠棧,隻不過是隱式的。
- 先將根節點壓入棧中。
- 彈出棧中的節點,將彈出節點的右子節點壓入棧中,再將彈出節點的左子樹壓入棧中。
- 重復步驟2,直到棧為空。
public static void preOrder(TreeNode root) { if (root == null) { return; } Stack<TreeNode> stack = new Stack<>(); stack.push(root); while (!stack.empty()) { TreeNode node = stack.pop(); // 打印節點值 System.out.print(node.value + " "); if (node.right != null) { stack.push(node.right); } if (node.left != null) { stack.push(node.left); } } }
後序遍歷遞歸實現:先序遍歷反過來,就不贅述瞭。
public static void postOrderByRecursion(TreeNode root) { postOrderByRecursion(root.left); postOrderByRecursion(root.right); System.out.println(root.value); }
後序遍歷非遞歸實現:後序遍歷就是先序遍歷反過來,所以需要兩個棧,多出來的棧用來反向輸出。
public static void postOrder(TreeNode root) { if (root == null) { return; } Stack<TreeNode> s1 = new Stack<>(); Stack<TreeNode> s2 = new Stack<>(); s1.push(root); while (!s1.empty()) { TreeNode node = s1.pop(); s2.push(node); if (node.left != null) { s1.push(node.left); } if (node.right != null) { s1.push(node.right); } } while (!s2.empty()) { System.out.println(s2.pop().value); } }
二、中序遍歷
中序遍歷先遍歷左子樹,再遍歷根節點,再遍歷右子樹。
遞歸遍歷:
public static void inOrderByRecursion(TreeNode root) { if (root == null) { return; } inOrderByRecursion(root.left); // 打印節點值 System.out.println(root.value); inOrderByRecursion(root.right); }
非遞歸遍歷:
- 將二叉樹的左側“邊”從上到下依次壓入棧中。
- 從棧中彈出節點
- 對以彈出節點的右子節點為根節點的子樹,重復步驟1。
- 重復2、3步驟,直到棧為空。
public static void inOrder(TreeNode root) { if (root == null) { return; } Stack<TreeNode> stack = new Stack<>(); TreeNode cur = root; while (cur != null) { stack.push(cur); cur = cur.left; } while (!stack.empty()) { TreeNode node = stack.pop(); System.out.println(node.value); cur = node.right; while (cur != null) { stack.push(cur); cur = cur.left; } } }
三、層序遍歷
層序遍歷顧名思義就是一層一層,從左到右的遍歷二叉樹。需要用到隊列這一數據結構。
- 將根節點推入隊列。
- 從隊列中取出一個節點。
- 先將取出節點的左子節點推入隊列,再將取出節點的右子節點推入隊列。
- 重復2、3步驟直到隊列中無節點可取。
public static void floorOrder(TreeNode root) { if (root == null) { return; } Queue<TreeNode> queue = new LinkedList<>(); queue.add(root); while (!queue.isEmpty()) { TreeNode node = queue.poll(); System.out.println(node.value); if (node.left != null) { queue.add(node.left); } if (node.right != null) { queue.add(node.right); } } }
到此這篇關於Java二叉樹的四種遍歷(遞歸與非遞歸)的文章就介紹到這瞭,更多相關Java二叉樹的四種遍歷內容請搜索WalkonNet以前的文章或繼續瀏覽下面的相關文章希望大傢以後多多支持WalkonNet!
推薦閱讀:
- Java二叉樹的四種遍歷方式詳解
- Java 二叉樹遍歷的常用方法
- Java數據結構之樹和二叉樹的相關資料
- C++實現LeetCode(144.二叉樹的先序遍歷)
- java數據結構圖論霍夫曼樹及其編碼示例詳解