二叉樹的遍歷方式有很多種:前序遍歷、中序遍歷、後序遍歷以及層序遍歷等,遍歷也可分遞歸與非遞歸方式,下面將用以下這顆二叉樹進行各個遍歷方式的講解:
———————————————————————— 下面是正文 —————————————————————————
一.先序遍歷(遞歸方式)
先序遍歷的遍歷順序爲:中左右。
按照此順序對上述二叉樹進行遍歷的步驟爲:
先訪問主結點:
再訪問左結點:
理論上是要訪問該結點的左結點,但是該結點的左結點不存在,所以訪問其右節點:
後來,訪問該結點的左結點,沒有,再訪問右結點,也沒有,所以以“1”爲主結點的左邊遍歷結束,開始遍歷右邊結點:
訪問左結點:
然後訪問其左結點,沒有,所以訪問其右結點:
最後訪問結點“3”的右結點,沒有,結束遍歷,所以前序遍歷最後輸出:
代碼使用遞歸的方式進行遍歷,代碼量少,但是佔用空間資源大:
void Preorder(Node* n)
{
if (n)
{
printf("%d ", n->data);
Preorder(n->left);
Preorder(n->right);
}
}
二.中序遍歷(遞歸)
中序遍歷的遍歷順序爲:左中右。
按照此順序對上述二叉樹進行遍歷的步驟爲:
先訪問左結點:
再訪問結點 “2” 的左結點,但是沒有,所以左邊遍歷結束,輸出中結點 “2” ,再訪問右結點,輸出“5”:
然後主結點 “1” 的左節點遍歷完成,訪問中結點,也就是自己,輸出 “1” :
開始訪問 “1” 的右結點 “3” :
左結點存在,所以訪問其左結點:
再訪問 “6” 的左結點,但是不存在,所以訪問中結點,也就是自己,輸出“6”,訪問右結點:
身爲右結點的“13” 即沒有左結點也沒有右結點,所以輸出自己,跳回到 “3” :
理論上訪問完“3”的左結點後開始訪問其右結點的,但是不存在,所以輸出自己 “3” ,最後得出中序遍歷的結果:
代碼如下(遞歸方法):
void Middle_order(Node* n)
{
if (n)
{
Middle_order(n->left);
printf("%d ", n->data);
Middle_order(n->right);
}
}
三.後序遍歷 (遞歸)
後序遍歷的遍歷順序爲:左右中。
按照此順序對上述二叉樹進行遍歷的步驟爲:
先訪問左結點:
再訪問“2”的左結點,沒有,所以訪問右結點“5”:
訪問“5”的左右結點,沒有,所以輸出自己,箭頭指回“2”:
至此“1”的左邊結點遍歷完成,開始遍歷右邊結點,箭頭指向“3”:
訪問其左結點“6”:
隨後再訪問“6”的左結點,沒有,所以訪問其右結點“13”:
“13”沒有左右結點,所以輸出自己,箭頭指回“6”:
輸出“6”,箭頭指回“3”,輸出“3”,主結點“1”的右結點也遍歷完成,最後輸出中結點,也就是自己“1”:
最後得出中序遍歷的結果:
代碼如下(遞歸方法):
void Post_order(Node* n)
{
if (n)
{
Post_order(n->left);
Post_order(n->right);
printf("%d ", n->data);
}
}
四.前中後序非遞歸堆棧方法
使用堆棧的方法可以避免遞歸過程中遇到的空間資源浪費的問題,前中後序的堆棧方法都相類似,所以下面以中序遍歷爲例子進行講解,堆棧的核心思想是遍歷的結點存在,則壓入棧中,不存在,則將棧中數據壓出,第一步是先創建一個空棧:
按照先序遍歷的順序是中左右,所以先將主結點 “1” 壓入棧中:
隨後訪問其左結點 “2”,將其壓入棧中:
再訪問“2” 的左結點,沒有,所以從棧中壓出一個數據“2”:
隨後訪問右結點“5”,存在,所以將其壓入棧中:
隨後訪問“5”的左結點,不存在,所以從棧中壓出一個數據:
再訪問“5” 的右結點,沒有,所以再次從棧中壓出一個數據:
至此結點“1” 的左結點遍歷完成,開始遍歷其右結點“3”,壓入棧中:
然後訪問其左結點“6”,壓入棧中:
再訪問其左結點,不存在,所以壓出棧中一個數據:
訪問其右結點“13”,壓入棧中:
訪問“13”的左結點,不存在,從棧中壓出一個數據:
最後訪問“13”的右結點,不存在,所以壓出棧中的數據:
最後輸出中序遍歷後的結果:
中序遍歷代碼如下:
void Stack_Middle_order(Node* n)
{
Node* N = n; //創建二叉樹
Stack S = CreateStack(100); //創建棧
while (N || !IsEmpty(S))
{
while (N)
{
Push(S, N); //壓棧
N = N->left;
}
if (!IsEmpty(S)) //判斷棧堆是否爲空
{
N = Pop(S); //出棧
printf("%d ", N->data);
N = N->right;
}
}
}
五.層序遍歷
層序遍歷最簡單,就是從上往下進行遍歷,如以下二叉樹:
使用層序遍歷就可以按照順序進行輸出:1,2,3,5,6,13,代碼思路可以選擇使用隊列+遞歸來實現,根據隊列的“先進後出”的特性可以滿足層序遍歷的需求。