zoukankan      html  css  js  c++  java
  • 二叉树的非递归遍历

    【中序遍历】

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

    • 遇到一个结点,就把它压栈,并去遍历它的左子树
    • 左子树遍历结束后,从栈顶弹出这个结点并访问它
    • 然后按其右指针再去中序遍历该结点的右子树
     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 }
  • 相关阅读:
    kafka-python基本使用
    RabbitMq 消息队列详解
    Socket 编程
    python 进程, 线程 ,协程,锁,协程应用到爬虫的讲解
    python中with的用法
    为什么 Elasticsearch 需要堆内存来存储数据
    面向数据的架构
    跟我一起学Redis之看完这篇比常人多会三种类型实战(又搞了几个小时)
    跟我一起学.NetCore之熟悉的接口权限验证不能少(Jwt)
    跟我一起学.NetCore之WebApi接口裸奔有风险(Jwt)
  • 原文地址:https://www.cnblogs.com/utank/p/4269421.html
Copyright © 2011-2022 走看看