二叉树的三种遍历
前言:搞懂非递归和递归三种遍历,二叉树的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 }
运行结果: