《演算法筆記》7. 二叉樹基本演算法整理
阿新 • • 發佈:2020-07-28
[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) {