1. 程式人生 > >《演算法筆記》7. 二叉樹基本演算法整理

《演算法筆記》7. 二叉樹基本演算法整理

[TOC] # 1 二叉樹基本演算法 ## 1.1 二叉樹的遍歷 ### 1.1.1 二叉樹節點定義 ```Java Class Node{ // 節點的值型別 V value; // 二叉樹的左孩子指標 Node left; // 二叉樹的右孩子指標 Node right; } ``` ### 1.1.2 遞迴實現先序中序後序遍歷 > 先序:任何子樹的處理順序都是,先頭結點,再左子樹,再右子樹。先處理頭結點 > 中序:任何子樹的處理順序都是,先左子樹,再頭結點,再右子樹。中間處理頭結點 > 後序:任何子樹的處理順序都是,先左子樹,再右子樹,再頭結點。最後處理頭結點 對於下面的一棵樹: ``` graph TD 1-->2 1-->3 2-->4 2-->5 3-->6 3-->7 ``` 1、 先序遍歷為:1 2 4 5 3 6 7 2、 中序遍歷為:4 2 5 1 6 3 7 3、 後序遍歷為:4 5 2 6 7 3 1 ```Java package class07; public class Code01_RecursiveTraversalBT { public static class Node { public int value; public Node left; public Node right; public Node(int v) { value = v; } } public static void f(Node head) { if (head == null) { return; } // 1 此處列印等於先序 f(head.left); // 2 此處列印等於中序 f(head.right); // 3 此處列印等於後序 } // 先序列印所有節點 public static void pre(Node head) { if (head == null) { return; } // 列印頭 System.out.println(head.value); // 遞迴列印左子樹 pre(head.left); // 遞迴列印右子樹 pre(head.right); } // 中序遍歷 public static void in(Node head) { if (head == null) { return; } in(head.left); System.out.println(head.value); in(head.right); } // 後序遍歷 public static void pos(Node head) { if (head == null) { return; } pos(head.left); pos(head.right); System.out.println(head.value); } public static void main(String[] args) { Node head = new Node(1); head.left = new Node(2); head.right = new Node(3); head.left.left = new Node(4); head.left.right = new Node(5); head.right.left = new Node(6); head.right.right = new Node(7); pre(head); System.out.println("========"); in(head); System.out.println("========"); pos(head); System.out.println("========"); } } ``` > 結論:對於樹的遞迴,每個節點實質上會到達三次,例如上文的樹結構,對於f函式,我們傳入頭結點,再呼叫左樹再呼叫右樹。實質上經過的路徑為1 2 4 4 4 2 5 5 5 2 1 3 6 6 6 3 7 7 7 3 1。我們在每個節點三次返回的基礎上,第一次到達該節點就列印,就是先序,第二次到達該節點列印就是中序,第三次到達該節點就是後序。 > 所以先序中序後序,只是我們的遞迴順序加工出來的結果! ### 1.1.3 非遞迴實現先序中序後序遍歷 > 思路:由於任何遞迴可以改為非遞迴,我們可以使用壓棧來實現。用先序實現的步驟,其他類似: > 步驟一,把節點壓入棧中,彈出就列印 > 步驟二,如果有右孩子先壓入右孩子 > 步驟三,如果有左孩子壓入左孩子 ```Java package class07; import java.util.Stack; public class Code02_UnRecursiveTraversalBT { public static class Node { public int value; public Node left; public Node right; public Node(int v) { value = v; } } // 非遞迴先序 public static void pre(Node head) { System.out.print("pre-order: "); if (head != null) {