二叉樹的非遞迴遍歷(先序、中序、後序和層序遍歷)
阿新 • • 發佈:2018-11-17
[前文]
二叉樹的非遞迴遍歷有 先序遍歷、中序遍歷 、後續遍歷 和 層序遍歷。
非遞迴演算法實現的基本思路:使用堆疊。而層序遍歷的實現:使用佇列。
如下圖所示的二叉樹:
前序遍歷順序為:ABCDE (先訪問根節點,然後先序遍歷其左子樹,最後先序遍歷其右子樹)
中序遍歷順序為:CBDAE (先中序遍歷其左子樹,然後訪問很節點,最後中序遍歷其右子樹)
後續遍歷順序為:CDBEA (先後序遍歷其左子樹,然後後續其右子樹,最後訪問根節點)
層序遍歷順序為:ABECD (由上至下、從左到右遍歷二叉樹)
[準備]
1. 堆疊的儲存結構和相關操作(具體見: 堆疊的定義與操作——順序儲存和鏈式儲存)
2. 佇列的儲存結構和相關操作(具體見:佇列的定義與操作——順序儲存和鏈式儲存)
3. 建立二叉樹。
1 typedef struct TreeNode *BinTree; 2 struct TreeNode { 3 char Data; 4 BinTree Left; 5 BinTree Right; 6 }; 7 8 BinTree CreateBinTree(BinTree T) 9 { 10 char c; 11 scanf("%c", &c); 12 if ( c != '#' ) { 13 T = (BinTree)malloc(sizeof(struct TreeNode)); 14 T->Data = c; 15 T->Left = CreateBinTree(T->Left); 16 T->Right = CreateBinTree(T->Right); 17 } 18 else { 19 T = NULL; 20 } 21 return T; 22 }
[實現]
1. 先序遍歷
1 void PreOrderTraverse(BinTree BT) 2 { 3 BinTree T = BT; 4 Stack S = CreateStack(); /* 建立並初始化堆疊 */ 5 while ( T || !IsEmpty(S) ) { 6 while ( T ) { /* 一直向左並將沿途節點壓入棧底 */ 7 printf("%c ", T->Data); /* 列印節點資料 */ 8 Push(S, T); 9 T = T->Left; 10 } 11 if ( !IsEmpty(S) ) { 12 T = Pop(S); /* 節點彈出堆疊 */ 13 T = T->Right; /* 轉向右子樹 */ 14 } 15 } 16 }
2.中序遍歷
1 void InOrderTraverse(BinTree BT) 2 { 3 BinTree T = BT; 4 Stack S = CreateStack(); /* 建立並初始化堆疊 */ 5 while ( T || !IsEmpty(S) ) { 6 while ( T ) { /* 一直向左並將沿途節點壓入棧底 */ 7 Push(S, T); 8 T = T->Left; 9 } 10 if ( !IsEmpty(S) ) { 11 T = Pop(S); /* 節點彈出堆疊 */ 12 printf("%c ", T->Data); /* 列印節點資料 */ 13 T = T->Right; /* 轉向右子樹 */ 14 } 15 } 16 }
3. 後序遍歷
struct Node { BinTree BT; char Tag; }; typedef struct Node *PtrToNode; void PostOrderTraverse(BinTree T) { BinTree P = T; struct Node *PNode; Stack S = CreateStack(); while ( P || !IsEmpty(S) ) { // 遍歷左子樹 while ( P ) { PNode = (struct Node*)malloc(sizeof(struct Node)); PNode->BT = P; PNode->Tag = 'L'; // 第一次被標記 Push(S, PNode); P = P->Left; } // 棧不空 並且 棧頂元素 是第二次被標記 while ( !IsEmpty(S) && GetTop(S)->Tag == 'R' ) { PNode = Pop(S); printf("%c ", PNode->BT->Data); } if ( !IsEmpty(S) ) { PNode = GetTop(S); PNode->Tag = 'R'; // 第二次被標記 P = PNode->BT; P = P->Right; // 轉向右子樹 } } }
4. 層序遍歷
1 void LevelOrderTraverse(BinTree BT) 2 { 3 Queue Q; 4 ElementType T; 5 6 if ( !BT ) return; // 若是空樹則返回 7 8 Q = CreateQueue(); // 建立空佇列 9 AddQ(Q, BT); 10 while ( !IsEmpty(Q) ) { 11 T = DeleteQ(Q); 12 printf("%c ", T->Data); 13 if ( T->Left ) AddQ(Q, T->Left); 14 if ( T->Right ) AddQ(Q, T->Right); 15 } 16 }