| 图与树搜索算法 |
| --- |
| * α–β
* A\*
* B\*（英语：）
* 回溯
* 集束（英语：）
* 贝尔曼-福特
* 最佳优先（英语：）
* 双向
* 布魯瓦卡（英语：）
* 分支限界
* BFS
* 大英博物馆
* D\*（英语：）
* DFS
* 深度限制（英语：）
* 迪杰斯特拉
* 愛德蒙斯（英语：）
* 弗洛伊德
* 边缘搜索
* 爬山
* IDA\*（英语：）
* 迭代加深
* 约翰逊（英语：）
* 跳点（英语：）
* 克鲁斯克尔
* 词典BFS（英语：）
* LPA\*（英语：）
* 普里姆
* SMA\*（英语：）
* 最短路径快速
 |
| 
分类 |
| * 图算法
* 搜索算法
* 算法列表（英语：）
 |
| 
相关主题 |
| * 动态规划
* 图的遍历
* 树的遍历
 |
| * 
* 论
* 编
 |

在计算机科学裡，**树的遍历**（也称为或**树的搜索**）是一种圖的遍歷，指的是按照某种规则，不重复地访问某种樹的所有节点的过程。具体的访问操作可能是检查节点的值、更新节点的值等。不同的遍历方式，其访问节点的顺序是不一样的。以下虽然描述的是二叉树的遍历算法，但它们也适用于其他树形结构。

遍历的种类
-----

与那些基本上都有标准遍历方式（通常是按线性顺序）的线性数据结构（如链表、一维数组）所不同的是，树结构有多种不同的遍历方式。从二叉树的根节点出发，节点的遍历分为三个主要步骤：对当前节点进行操作（称为"访问"节点）、遍历左边子节点、遍历右边子节点。这三个步骤的先后顺序也是不同遍历方式的根本区别。

由于从给定的某个节点出发，有多个可以前往的下一个节点（树不是线性数据结构），所以在顺序计算（即非并行计算）的情况下，只能推迟对某些节点的访问——即以某种方式保存起来以便稍后再访问。常见的做法是采用堆栈（LIFO）或队列（FIFO）。由于树本身是一种自我引用（即递归定义）的数据结构，因此很自然也可以用递归方式，或者更准确地说，用共递归，来实现延迟节点的保存。这时（采用递归的情况）这些节点被保存在呼叫堆疊中。

遍历方式的命名，源于其访问节点的顺序。最简单的划分：是深度优先（先访问子节点，再访问父节点，最后是第二个子节点）？还是广度优先（先访问第一个子节点，再访问第二个子节点，最后访问父节点）？ 深度优先可进一步按照根节点相对于左右子节点的访问先后来划分。如果把左节点和右节点的位置固定不动，那么根节点放在左节点的左边，称为前序（pre-order）、根节点放在左节点和右节点的中间，称为中序（in-order）、根节点放在右节点的右边，称为后序（post-order）。对广度优先而言，遍历没有前序中序后序之分：给定一组已排序的子节点，其"广度优先"的遍历只有一种唯一的结果。

### 深度优先遍历

分作**前序走訪**、**中序走訪**、**后序走訪**，前、中、後代表根節點在走訪時的位置。以下透過C語言實作，並均使用递归方法。

#### 前序遍历

深度优先遍历（前序遍历）  
F, B, A, D, C, E, G, I, H.
前序遍历（Pre-Order Traversal）是依序以根節點、左節點、右節點為順序走訪的方式。
其遍歷順序是：


|  |  |  |  |  |  |  |  |  |  |  |  |  |  |
| --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- |
| 1 | 

|  |  |  |  |  |  |  |  |
| --- | --- | --- | --- | --- | --- | --- | --- |
| 2 | 

|  |  |
| --- | --- |
|   | 3 |
|   |
|   | 4 |
|   |

 |
|   |
|   | 5 |
|   |

 |
|   |

```
void pre\_order\_traversal(TreeNode \*root) {
 // Do Something with root
 if (root->lchild != NULL) //若其中一側的子樹非空則會讀取其子樹
 pre\_order\_traversal(root->lchild);
 if (root->rchild != NULL) //另一側的子樹也做相同事
 pre\_order\_traversal(root->rchild);
}

```

#### 中序遍历

深度优先遍历（中序遍历）  
A, B, C, D, E, F, G, H, I.
中序遍历（In-Order Traversal）是依序以左節點、根節點、右節點為順序走訪的方式。
其遍歷順序是：


|  |  |  |  |  |  |  |  |  |  |  |  |  |  |
| --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- |
| 4 | 

|  |  |  |  |  |  |  |  |
| --- | --- | --- | --- | --- | --- | --- | --- |
| 2 | 

|  |  |
| --- | --- |
|   | 1 |
|   |
|   | 3 |
|   |

 |
|   |
|   | 5 |
|   |

 |
|   |

```
void in\_order\_traversal(TreeNode \*root) {
 if (root->lchild != NULL) //若其中一側的子樹非空則會讀取其子樹
 in\_order\_traversal(root->lchild);
 // Do Something with root
 if (root->rchild != NULL) //另一側的子樹也做相同事
 in\_order\_traversal(root->rchild);
}

```

#### 后序遍历

深度优先搜索（后序遍历）：  
A, C, E, D, B, H, I, G, F.
后序遍历（Post-Order Traversal）是依序以左節點、右節點、根節點為順序走訪的方式。
其遍歷順序是：


|  |  |  |  |  |  |  |  |  |  |  |  |  |  |
| --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- |
| 5 | 

|  |  |  |  |  |  |  |  |
| --- | --- | --- | --- | --- | --- | --- | --- |
| 3 | 

|  |  |
| --- | --- |
|   | 1 |
|   |
|   | 2 |
|   |

 |
|   |
|   | 4 |
|   |

 |
|   |

```
void post\_order\_traversal(TreeNode \*root) {
 if (root->lchild != NULL) //若其中一側的子樹非空則會讀取其子樹
 post\_order\_traversal(root->lchild);
 if (root->rchild != NULL) //另一側的子樹也做相同事
 post\_order\_traversal(root->rchild);
 // Do Something with root
}

```

### 广度优先遍历

和深度优先遍历不同，广度优先遍历会先访问离根节点最近的节点。二叉树的广度优先遍历又称按层次遍历。算法借助队列实现。
其遍歷順序是：


|  |  |  |  |  |  |  |  |  |  |  |  |  |  |
| --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- |
| 1 | 

|  |  |  |  |  |  |  |  |
| --- | --- | --- | --- | --- | --- | --- | --- |
| 2 | 

|  |  |
| --- | --- |
|   | 4 |
|   |
|   | 5 |
|   |

 |
|   |
|   | 3 |
|   |

 |
|   |

广度优先遍历 - 层次遍历：  
 F, B, G, A, D, I, C, E, H.

```
void level(TreeNode \*node)
{
 Queue \*queue = initQueue();
 enQueue(queue, node);

 while (!isQueueEmpty(queue))
 {
 TreeNode \*curr = deQueue(queue);

 // Do Something with curr

 if (curr->lchild != NULL)
 enQueue(queue, curr->lchild);
 if (curr->rchild != NULL)
 enQueue(queue, curr->rchild);
 }
}

```

多叉树的遍历
------

### 深度优先遍历

先訪問根結點，後選擇一子結點訪問並訪問該節點的子結點，持續深入後再依序訪問其他子樹，可以輕易用遞迴或棧的方式實現。

```
void travel(treenode\* nd){
 for(treenode\* nex :　nd->childs){ //childs存放指向其每個子結點的指標
 travel(nex); 
 }
 return;
}

```

参见
--

* 树 (数据结构)
* 图的遍历
* 《算法导论》
* 《计算机程序设计艺术》

参考資料
----



|  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |
| --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- |
| 

| * 
* 论
* 编
数据结构 |
| --- |
|  |
| 类型 | 
* 集合
* 容器

 |
|  |
| 抽象类型 | 
* 关联数组
	+ 多重关连数组（英语：）
* 列表
* 堆栈
* 队列
	+ 双端队列
* 优先队列
	+ 双端优先队列
* 集合
	+ 多重集
	+ 併查集
* 可持久化数据结构
	+ 线段树

 |
|  |
| 数组 | 
* 字串
* 位数组
* 环形缓冲器
* 动态数组
* 哈希表
* 哈希数组树（英语：）
* 稀疏矩阵

 |
|  |
| 链（英语：） | 
* 关联表（英语：）
* 链表
* 跳跃列表
* 松散链表（英语：）
* 异或链表

 |
|  |
| 树 | 
* 线段树
* 自平衡二叉查找树
* B树
* 二叉树
	+ AA树
	+ AVL树
	+ 红黑树
	+ 平衡树
	+ 伸展树
	+ 二叉查找树
* 堆
	+ 二叉堆
	+ 左偏树
	+ 二项堆
	+ 斐波那契堆
* R树
	+ R\*树
	+ R+树
	+ Hilbert R树（英语：）
* 前缀树
	+ 哈希树

 |
|  |
| 图 | 
* 有向图
* 有向无环图
* 二元决策图
* 无向图
* 确定性非循环有限自动机（英语：）

 |
|  |
| 数据结构术语 |

 |

|  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |
| --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- |
| 

| * 
* 论
* 编
计算机科学中的树 |
| --- |
|  |
| 二叉树 | 
* 二元搜尋樹
* 笛卡尔树
* MVP树
* Top tree（英语：）
* T树
* 线索二叉树

 |
|  |
| 自平衡二叉查找树 | 
* AA树
* AVL树
* 左倾红黑树
* 红黑树
* 替罪羊树
* 伸展树
* 树堆
* 加权平衡树

 |
|  |
| B树 | 
* B+树
* B\*树
* Bx树
* UB树
* 2-3树
* 2-3-4树
* (a,b)-树
* Dancing tree（英语：）
* H树

 |
|  |
| 堆 | 
* 二叉堆
* 二项堆
* 斐波那契堆
* 左偏树
* 配对堆
* 斜堆
* Van Emde Boas tree（英语：）

 |
|  |
| Trie | 
* 后缀树
* 基数树
* 三叉查找树
* X-快速前缀树
* Y-快速前缀树
* AC自动机

 |
|  |
| 二叉空间分割（BSP）树 | 
* 四叉树
* 八叉树
* *k*-d树
* 隐式*k*-d树
* VP树

 |
|  |
| 非二叉树 | 
* 指数树（英语：）
* 融合树（英语：）
* PQ树（英语：）
* SPQR树（英语：）

 |
|  |
| 空间数据分割树 | 
* R树
* R\*树
* R+树
* X树
* M树
* 線段樹 (儲存區間)
* 线段树 (区间查询)
	+ 可持久化线段树
* 希尔伯特R树
* 优先R树

 |
|  |
| 其他树 | 
* 散列日历
* 散列树
* Finger tree（英语：）
* 顺序统计树
* Metric tree（英语：）
* Cover tree（英语：）
* BK树
* Doubly chained tree（英语：）
* iDistance（英语：）
* Link-cut tree（英语：）
* Log-structured merge-tree（英语：）
* 树状数组
* 哈希树

 |

 |