【中序遍历】
中序遍历非递归遍历算法:
- 遇到一个结点,就把它压栈,并去遍历它的左子树;
- 当左子树遍历结束后,从栈顶弹出这个结点并访问它;
- 然后按其右指针再去中序遍历该结点的右子树;
1 void InOrderTraversal_ext(BinTree Bt) 2 { 3 BinTree pStack[100]; 4 int top = -1; 5 Position pBt = Bt; 6 7 while(pBt != NULL || top > -1) /* Bt || !isEmpty(pStack) */ 8 { 9 // TODO: 1.遇到一个结点,就把它压栈,并去遍历它的左子树 10 while(pBt) 11 { 12 pStack[++top] = pBt; 13 pBt = pBt->Left; 14 } 15 // TODO: 2.当左子树遍历结束后,从栈顶弹出这个结点并访问它 16 if(top > -1) /* !isEmpty(pStack) */ 17 { 18 pBt = pStack[top--]; 19 printf("%c ", pBt->Data); 20 // TODO: 3.然后按其右指针再去中序遍历该结点的右子树 21 pBt = pBt->Right; /* 转向右子树 */ 22 } 23 } 24 }
【先序遍历】
1 void PreOrderTraversal_ext(BinTree Bt) 2 { 3 BinTree pStack[100]; 4 int top = -1; 5 Position pBt = Bt; 6 7 while(pBt != NULL || top > -1) /* Bt || !isEmpty(pStack) */ 8 { 9 while(pBt) 10 { 11 // 与中序遍历不同点就是在第一次压栈的时候就进行访问了 12 printf("%c ", pBt->Data); 13 pStack[++top] = pBt; 14 pBt = pBt->Left; 15 } 16 if(top > -1) /* !isEmpty(pStack) */ 17 { 18 pBt = pStack[top--]; 19 //printf("%c ", pBt->Data); 20 pBt = pBt->Right; /* 转向右子树 */ 21 } 22 } 23 }
【后序遍历】
后序遍历中,要保证根结点在左孩子和右孩子访问之后才能访问。因此对于任一结点P,先将其入栈。如果P不存在左孩子和右孩子,则可以直接访问它;或者P存在左孩子或者右孩子,但是其左孩子和右孩子都已被访问过了,则同样可以直接访问该结点。若非上述两种情况,则将P的右孩子和左孩子依次入栈,这样就保证了每次取栈顶元素的时候,左孩子在右孩子前面被访问,左孩子和右孩子都在根结点前面被访问。
1 void PostOrderTraversal_ext(BinTree Bt) 2 { 3 BinTree pStack[100]; 4 int top = -1; 5 Position pBt = Bt; 6 Position pPre = NULL; 7 8 pStack[++top] = Bt; 9 while(top > -1) 10 { 11 // 只探测栈顶的结点是否满足被访问的条件 12 // 当前结点为叶结点 或者 当前结点的左孩子或右孩子已经被访问过来,则满足访问条件 13 pBt = pStack[top]; 14 if((pBt->Left == NULL && pBt->Right == NULL) 15 || (pPre != NULL && (pPre == pBt->Left || pPre == pBt->Right))) 16 { 17 printf("%c ", pBt->Data); 18 top--; 19 pPre = pBt; 20 } 21 else 22 { 23 if(pBt->Right != NULL) 24 { 25 pStack[++top] = pBt->Right; 26 } 27 if(pBt->Left != NULL) 28 { 29 pStack[++top] = pBt->Left; 30 } 31 } 32 } 33 }
后序遍历思路,参考链接:http://www.cnblogs.com/dolphin0520/archive/2011/08/25/2153720.html
【层序遍历】
层序遍历的队列实现:遍历从根结点开始,首先将根结点入队,然后开始执行循环:结点出队、访问该结点、其左右儿子结点入队。
层序基本过程:先将根结点入队,然后:
- 从队列中取出一个元素;
- 访问该元素所指结点;
- 若该元素所指结点的左、右孩子非空,则将其左、右孩子的顺序入队;
1 void LevelOrderTraversal(BinTree Bt) 2 { 3 BinTree pQueue[100]; 4 int head = 0; 5 int tail = 0; 6 BinTree pBt; 7 8 pQueue[tail++] = Bt; 9 while(tail != head) 10 { 11 pBt = pQueue[head++]; 12 printf("%c ", pBt->Data); 13 if(pBt->Left != NULL) 14 { 15 pQueue[tail++] = pBt->Left; 16 } 17 if(pBt->Right != NULL) 18 { 19 pQueue[tail++] = pBt->Right; 20 } 21 } 22 }