二叉树的非递归遍历

【中序遍历】

中序遍历非递归遍历算法:

  • 遇到一个结点,就把它压栈,并去遍历它的左子树
  • 左子树遍历结束后,从栈顶弹出这个结点并访问它
  • 然后按其右指针再去中序遍历该结点的右子树
 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 }

 

你可能感兴趣的:(二叉树)