前言:搞懂非遞歸和遞歸三種遍歷,二叉樹的90%的問題算你全搞定了。
先序遍歷:根,左子樹,右子樹
中序遍歷:左子樹,根,右子樹
后序遍歷:左子樹,右子樹,根
先序遍歷序列的特點:ABCDEFGHIJK A是樹根,左子樹可能是BCDEFGH右子樹可能是IJK 對於B左子樹可能是CD,右子樹可能是EFGH。即,任一結點,它的右側的一段元素依次是左子樹,右子樹。
中序遍歷序列的特點:ABCDEFGHIJK 對任一結點,左側一段是它的左子樹,右側一段是它的右子樹。
后序遍歷序列的特點:ABCDEFGHIJK K是樹根,對於任一結點,左側一段結點,從左向右依次是左子樹,右子樹。
根據先序中序 或 后序中序 能還原一棵二叉樹,根據 先序和后序 不能還原一棵二叉樹。
遞歸遍歷:
24 /*先序遞歸遍歷*/ 25 void DLR(BiTree *T) { 26 if(*T != NULL) { 27 printf("%c ",(*T)->data); 28 DLR(&(*T)->lchild); 29 DLR(&(*T)->rchild); 30 } 31 } 32 /*中序遞歸遍歷*/ 33 void LDR(BiTree *T) { 34 if(*T != NULL) { 35 LDR(&(*T)->lchild); 36 printf("%c ",(*T)->data); 37 LDR(&(*T)->rchild); 38 } 39 } 40 41 /*后序遞歸遍歷*/ 42 void LRD(BiTree *T) { 43 if(*T == NULL) 44 return; 45 LRD(&(*T)->lchild); 46 LRD(&(*T)->rchild); 47 printf("%c ",(*T)->data); 48 }
非遞歸遍歷

1 /*非遞歸中序遍歷*/ 2 void LDR_no_recursion(BiTree *T) { 3 BiTree stack[100]; 4 int top = -1; 5 if (*T == null) 6 return; 7 BiTree p = *T; 8 while (p) { 9 stack[++top] = p; 10 p = p->lchild; 11 } 12 while (top != -1) { 13 while (top != -1 && stack[top]->rchild == null){ 14 p = stack[top]; 15 printf("%c ",p->data); 16 --top; 17 } 18 if (top == -1) 19 return; 20 else { 21 p = stack[top]->rchild; 22 printf("%c ", stack[top]->data); 23 --top; 24 while (p) { 25 stack[++top] = p; 26 p = p->lchild; 27 } 28 } 29 } 30 } 31 /*后序非遞歸遍歷*/ 32 void LRD_no_recursion(BiTree *T) { 33 34 if (*T == null) 35 return; 36 SBiTNode st; 37 SBiTNode stack[100];//總是忘記帶* 38 int top = -1; 39 BiTree p = *T; 40 while (p) { 41 top++; 42 stack[top].elem = p; 43 stack[top].flag = 0; 44 p = p->lchild; 45 } 46 while (top != -1) { 47 st = stack[top]; 48 if (st.elem->rchild == null || st.flag == 1) { 49 printf("%c ", st.elem->data); 50 --top; 51 } 52 else { 53 stack[top].flag = 1; 54 p = st.elem->rchild; 55 while (p) { 56 top++; 57 stack[top].elem = p; 58 stack[top].flag = 0; 59 p = p->lchild; 60 } 61 } 62 } 63 }
三種遍歷完整源代碼

1 #include"頭文件.h" 2 3 typedef struct node { 4 char data; 5 struct node *lchild, *rchild; 6 }BiTNode,*BiTree; 7 8 typedef struct { 9 BiTree elem; 10 int flag; 11 }SBiTNode;//棧結點 12 13 /*先序創建二叉樹*/ 14 void CreateTree(BiTree *T) { 15 char ch; 16 scanf_s("%c", &ch); 17 if (ch == '#') { 18 *T = null; 19 } 20 else { 21 *T = (BiTree)malloc(sizeof(BiTNode)); 22 if (*T == null) exit(-1); 23 (*T)->data = ch; 24 CreateTree(&(*T)->lchild); 25 CreateTree(&(*T)->rchild); 26 } 27 } 28 /*先序遞歸遍歷*/ 29 void DLR(BiTree *T) { 30 if (*T) { 31 printf("%c ", (*T)->data); 32 DLR(&(*T)->lchild); 33 DLR(&(*T)->rchild); 34 } 35 } 36 /*中序遞歸遍歷*/ 37 void LDR(BiTree *T) { 38 if (*T) { 39 LDR(&(*T)->lchild); 40 printf("%c ", (*T)->data); 41 LDR(&(*T)->rchild); 42 } 43 } 44 /*非遞歸中序遍歷*/ 45 void LDR_no_recursion(BiTree *T) { 46 BiTree stack[100]; 47 int top = -1; 48 if (*T == null) 49 return; 50 BiTree p = *T; 51 while (p) { 52 stack[++top] = p; 53 p = p->lchild; 54 } 55 while (top != -1) { 56 while (top != -1 && stack[top]->rchild == null){ 57 p = stack[top]; 58 printf("%c ",p->data); 59 --top; 60 } 61 if (top == -1) 62 return; 63 else { 64 p = stack[top]->rchild; 65 printf("%c ", stack[top]->data); 66 --top; 67 while (p) { 68 stack[++top] = p; 69 p = p->lchild; 70 } 71 } 72 } 73 } 74 /*后序遍歷*/ 75 void LRD(BiTree *T) { 76 if (*T) { 77 LRD(&(*T)->lchild); 78 LRD(&(*T)->rchild); 79 printf("%c ", (*T)->data); 80 } 81 } 82 /*后序非遞歸遍歷*/ 83 void LRD_no_recursion(BiTree *T) { 84 85 if (*T == null) 86 return; 87 SBiTNode st; 88 SBiTNode stack[100];//總是忘記帶* 89 int top = -1; 90 BiTree p = *T; 91 while (p) { 92 top++; 93 stack[top].elem = p; 94 stack[top].flag = 0; 95 p = p->lchild; 96 } 97 while (top != -1) { 98 st = stack[top]; 99 if (st.elem->rchild == null || st.flag == 1) { 100 printf("%c ", st.elem->data); 101 --top; 102 } 103 else { 104 stack[top].flag = 1; 105 p = st.elem->rchild; 106 while (p) { 107 top++; 108 stack[top].elem = p; 109 stack[top].flag = 0; 110 p = p->lchild; 111 } 112 } 113 } 114 } 115 int main() { 116 BiTree T; 117 printf("創建樹:\n"); 118 CreateTree(&T); 119 printf("遞歸先序遍歷:\n"); 120 DLR(&T); printf("\n"); 121 printf("非遞歸先序遍歷:\n"); 122 123 printf("遞歸中序遍歷:\n"); 124 LDR(&T); printf("\n"); 125 printf("非遞歸中序遍歷:\n"); 126 LDR_no_recursion(&T); printf("\n"); 127 printf("遞歸后序遍歷:\n"); 128 LRD(&T); printf("\n"); 129 printf("非遞歸后序遍歷:\n"); 130 LRD_no_recursion(&T); printf("\n"); 131 132 system("pause"); 133 return 0; 134 }
運行結果: