前序 | 中序 | 後序 | 層序 |
一、前序遍歷
步驟:根節點->左子節點->右子節點
適用場合:在第一次遍歷到節點時就執行操作,一般只是想遍歷執行操作(或輸出結果)可選用前序遍歷。
二、中序遍歷
步驟:左子節點->根節點->右子節點
適用場合:對於二分搜索樹,中序遍歷的操作順序(或輸出結果順序)是符合從小到大(或從大到小)順序的,故要遍歷輸出排序好的結果需要使用中序遍歷。
三、後序遍歷
步驟:左子節點->右子節點->根節點
適用場合:後續遍歷的特點是執行操作時,肯定已經遍歷過該節點的左右子節點,故適用於要進行破壞性操作的情況,比如刪除所有節點。
四、層序遍歷
步驟:按層,從上到下,從左到右遍歷
適用場合:
五、深度優先遍歷(Depth First Search)
步驟:對每一個可能的分支路徑深入到不能再深入爲止,而且每個節點只能訪問一次。
深度優先遍歷需要使用到棧這種數據結構,棧具有先進後出的特點。
如上圖,我們來分析下深度優先遍歷的過程。
- 首先根節點A入棧,stack(A)。
- 將A節點彈出,因爲A存在 B C兩個子節點,根據定義和棧特點,首先將C(右兒子)壓- 入棧中,然後將B(左兒子)壓入棧中,stack(C B)
- 彈出棧頂元素B節點彈出,將節點 E 和 D壓入棧中,stack(C E D)。
- 彈出棧頂元素D,由於節點D只存在一個子節點H,因此H直接入棧,stack(C E H).
- 彈出棧頂元素H,元素H不存在子元素,stack(C E).
- 彈出棧頂元素E,元素E不存在子元素,stack©.
- 彈出棧頂元素C,子節點G F分別入棧,stack(G F).
- F出棧,stack(G)。
- G出棧,stack()。
- 遍歷結束。
深度優先遍歷的結果爲: A B D H E C F G.
六、廣度優先遍歷(Breadth First Search)
步驟:對每一層節點依次訪問,訪問完一層進入下一層,而且每個節點只能訪問一次。
對於上面的例子來說,廣度優先遍歷的 結果是:A,B,C,D,E,F,G,H(假設每層節點從左到右訪問)。
廣度優先遍歷需要使用到隊列這種數據結構,隊列具有先進先出的特點。
如上圖所示,我們來分析廣度優先遍歷的過程。
- 首先將A節點插入隊列中,queue(A);
- 將A節點彈出,同時將A的子節點B,C插入隊列中,此時B在隊列首,C在隊列尾部,queue(B,C);
- 將B節點彈出,同時將B的子節點D,E插入隊列中,此時C在隊列首,E在隊列尾部,queue(C,D,E);
- 將C節點彈出,同時將C的子節點F,G插入隊列中,此時D在隊列首,G在隊列尾部,queue(D,E,F,G);
- 將D節點彈出,同時將D節點的子節點H插入隊列中,此時E在隊列首,H在隊列尾部,queue(E,F,G,H);
- E F G H分別彈出(這四個節點均不存在子節點)。
廣度優先遍歷結果爲:A B C D E F G H