二叉樹三種遍歷方式 遞迴和非遞迴

2021-08-29 20:46:32 字數 2474 閱讀 1706

樹形結構是一類重要的非線性資料結構。其中以樹和二叉樹是最為常用。

二叉樹有四種遍歷順序:先序遍歷(前序遍歷),中序遍歷,後序遍歷,層序遍歷。

這三種遍歷的方式其實是由遍歷的根結點的順序來定義的。

先序遍歷:先訪問根結點,再遍歷它的左子樹,最後遍歷它的右子樹。

中序遍歷:先遍歷左子樹,然後訪問根結點,最後遍歷它的右子樹。並且在遍歷左右子樹的時候。仍然是先遍歷左子樹,然後訪問根節點,最後遍歷右子樹。

後序遍歷:先遍歷左子樹,然後遍歷右子樹,最後訪問根結點。在遍歷左右子樹的時候同樣要先遍歷左子樹,然後遍歷右子樹,最後訪問根節點。

層序遍歷:從上往下逐層進行遍歷。

來看乙個例子:

先定義二叉樹的每個結點的資料域和指標域:

struct node;
上圖所示就是一棵二叉樹,那麼現在來遍歷這棵二叉樹。

先序遍歷:根據前面所述先序遍歷的定義,就會先遍歷a,輸出a,然後遍歷a的左子結點b,輸出b,此時又會將b看成一棵新的二叉樹的根結點,再遍歷b的左子結點c,輸出c,發現c沒有任何子結點了,就會回到b,再遍歷b的右子結點d,輸出d,發現d沒有任何子結點了,然後回到a,再遍歷a的右子結點,輸出e,然後發現e沒有左子結點,回到e,繼續遍歷e的右子結點f,輸出f,最後發現f沒有任何子結點了,至此,先序遍歷結束,所得到的結果就是abcdef

中序遍歷:先來到根結點a,然後遍歷它的左子樹,來到結點b,再遍歷b的左子樹,到結點c,繼續遍歷c的左子樹,發現沒有,然後返回到結點c,輸出c,再遍歷c的右子樹,發現也沒有,然後回到結點b,輸出b,再遍歷b的右子樹,來到結點d,繼續遍歷d的左子樹,沒有,然後回到d,輸出d,再遍歷d的右子樹也沒有,然後回到d,b的左右子樹已遍歷完,再返回上一層到結點a,此時,a的左子樹已經全部遍歷完,所以訪問根結點,輸出a,再開始遍歷a的右子樹,來到e,遍歷e的左子樹,發現為空,返回e,輸出e,再遍歷e的右子樹,到f,遍歷f的左子樹,發現為空,返回到f,輸出f,再遍歷f的右子樹,同樣為空,又返回f,然後e的子樹也遍歷完,返回a,至此,中序遍歷結束,所得到的結果是cbdaef。

後序遍歷:先到根結點a,然後遍歷它的左子樹,來到結點b,再遍歷b的左子樹,到結點c,繼續遍歷c的左子樹,發現沒有,然後返回到結點c,再遍歷c的右子樹,發現也沒有,然後返回到結點c,輸出c,再遍歷b的右子樹,來到結點d,繼續遍歷d的左右子樹,發現均為空,於是返回到d,輸出d,b的左右子樹遍歷完,又返回到b,輸出b,a的左子樹已遍歷完,然後遍歷a的右子樹,到結點e,遍歷e的左子樹,發現為空,返回到e,再遍歷e的右子樹,來到f,遍歷f的左右子樹,發現均為空,返回到f,輸出f,然後e的左右子樹均已遍歷完,有返回到e,輸出e,此時a的左右子樹已遍歷完,回到a,輸出a,至此,後續遍歷結束,得到的結果為cdbfea。

層序遍歷:從上往下從左往右依次遍歷,結果就是abecdf。

接下來給出三種遍歷方式的遞迴版**:

先序遍歷:

void preorder(node *root)

中序遍歷:

void inorder(node *root)

後序遍歷:

void posorder(node *root)

下面給出三種遍歷方式的非遞迴版:

先序遍歷:

1.申請乙個空棧,將祖先結點壓入棧中。

2.彈出棧頂元素,因為是先序遍歷,所以直接輸出這個棧頂元素。因為是先序遍歷的遍歷順序是根-->左-->右,但是因為棧是先進後出,所以應該先推入右子結點,再推入左子結點(如果有左子結點和右子結點的話)。

3.不斷重複第2步,直到棧為空。

void preorder(node *root)

}

中序遍歷:

1.申請乙個空棧,將祖先結點壓入棧中。

2.如果當前結點不為空,就將結點壓入棧,然後讓結點變為當前結點的左子結點。如果當前結點為空,就取出棧頂元素並列印,然後彈出棧頂元素,再讓當前結點變為當前結點的右子結點。

3.不斷重複第2步,直到棧空並且當前結點為空的時候。

void inorder(node *root)

else}}

後序遍歷:

1.建立兩個空棧,乙個棧儲存結點元素,乙個棧儲存輸出的答案。

2.如果棧不為空,就彈出存結點元素的棧頂記為cur,然後將棧頂元素出棧,並且將cur壓入儲存答案的棧中,如果cur有左子結點就將左子結點壓入存結點元素的棧中,如果有右子結點,也將右子結點壓入這個棧中。

3.重複第2步,直到棧空。

void posorder(node *root)

while(!res.empty())

}

二叉樹三種遍歷方式 非遞迴

二叉樹的先序 中序 後序遍歷,採用非遞迴實現。非遞迴實現的乙個基本思路 在遍歷的過程中要用棧來儲存遍歷中經過的結點。include includetypedef char datatype 定義二叉樹型別的節點 typedef struct btnodebtree 建立二叉樹,以先序的方式輸入,如果...

二叉樹三種遍歷方式非遞迴實現

1.中序遍歷 應為輸出的子樹根的關鍵字位於其左子樹關鍵字值和右子樹的關鍵字值之間 同理,先序後序遍歷。1.先序遍歷非遞迴演算法 define maxsize 100 typedef struct sqstack void preorderunrec bitree t endwhile if stac...

二叉樹的三種非遞迴遍歷

一.前序遍歷 前序遍歷按照 根結點 左孩子 右孩子 的順序進行訪問。1.遞迴實現 void preorder1 bintree root 遞迴前序遍歷 2.非遞迴實現 根據前序遍歷訪問的順序,優先訪問根結點,然後再分別訪問左孩子和右孩子。即對於任一結點,其可看做是根結點,因此可以直接訪問,訪問完之後...