一、非递归后序遍历算法思想

后序遍历的非递归算法中节点的进栈次数是两个,即每个节点都要进栈两次,第二次退栈的时候才访问节点。

第一次进栈时,在遍历左子树的过程中将"根"节点进栈,待左子树访问完后,回溯的节点退栈,即退出这个"根"节点,但不能立即访问,只能借助于这个"根"去找该"根"的右子树,并遍历这棵右子树,直到该右子树全部遍历以后,再退出该"根"节点,并访问它。

所以为了记录节点是第一次还是第二次进栈,就在堆栈数据元素的结构中增加一个数据项:进栈标志。

(1)当节点非空时或堆栈非空时,执行(2),否则结束算法;

(2)当节点指针非空时,节点的进栈标志设为false,节点指针及进栈标志进栈,然后将节点指向进栈节点的左子树的根,重复(2),知道指针为空(最后一个进栈的是最左子树),节点指针为空时,转(3);

(3)堆栈非空时,从堆栈中退出一个节点的指针。如果退出的节点的进栈标志为true,说明该节点是第二次退栈,访问该接点,并将指针强制设为空,准备下一次退栈,并转(3),如果进栈标志为false,说明该节点是第一次退栈,将进栈标志设为true,然后将该节点指针及进栈标志进栈,再将指针指向它的右子树,转(1)。

二、代码实现

#include<stdio.h>
#include<stdlib.h>typedef char EType; struct BinaryTreeNode
{EType data;struct BinaryTreeNode *LChild;struct BinaryTreeNode *RChild;
};
typedef BinaryTreeNode BinaryTree;typedef struct SType
{BinaryTreeNode *ptr;bool status;//进栈标志
}SType;typedef struct Stack
{SType *element;int top;int MaxSize;
}Stack;void CreatStack(Stack &S,int MaxStackSize);
bool IsEmpty(Stack &S);
bool IsFull(Stack &S);
bool GetTop(Stack &S,SType &result);
bool Pop(Stack &S,SType &result);
bool Push(Stack &S,SType &x);
void CreatBiTree(BinaryTreeNode **BT);
void PostOrderNoRecursive(BinaryTreeNode *BT);int main()
{BinaryTreeNode *BT = NULL;CreatBiTree(&BT);printf("后序遍历二叉树非递归算法输出为:");PostOrderNoRecursive(BT);printf("\n");return 0;
}void CreatStack(Stack &S,int MaxStackSize)
{S.MaxSize = MaxStackSize;S.element = new SType[S.MaxSize];S.top = -1;
}bool IsEmpty(Stack &S)
{if(S.top == -1)return true;return false;
}bool IsFull(Stack &S)
{if(S.top >= S.MaxSize-1)return true;return false;
}bool GetTop(Stack &S,SType &result)
{if(IsEmpty(S))return false;result = S.element[S.top];return true;
}bool Pop(Stack &S,SType &result)
{if(IsEmpty(S))return false;result = S.element[S.top];S.top--;return true;
}bool Push(Stack &S,SType &x)
{if(IsFull(S))return false;S.top++;S.element[S.top] = x;return true;
}void CreatBiTree(BinaryTreeNode **BT)
{EType tem;scanf("%c",&tem);if(' ' == tem){*BT = NULL;}else{*BT = new BinaryTreeNode;(*BT)->data = tem;CreatBiTree(&(*BT)->LChild);CreatBiTree(&(*BT)->RChild);}
}void PostOrderNoRecursive(BinaryTreeNode *BT)
{Stack S;SType temp;BinaryTreeNode *p = BT;int MaxStackSize = 50;CreatStack(S,MaxStackSize);while(p || !IsEmpty(S)){if(p)//找最左子树{temp.status = false;//设置该节点是第一次进栈temp.ptr = p;Push(S,temp);p = p->LChild;}else{if(!IsEmpty(S)){Pop(S,temp);p = temp.ptr;if(temp.status)//若该节点是第二次退栈,就访问,并设置p=0继续退栈{printf("%c\t",p->data);p = NULL;} else{temp.status = true;//设置该节点是第二次进栈Push(S,temp);p = p->RChild;//遍历该节点的右子树}}}}
}

三、 效果展示

建立这样一颗二叉树

所以按照前序遍历输入应该是:“AB_D_ _CE_ _ _”(其中“_”代表空格)

那么运行结果为:

数据结构-----后序遍历二叉树非递归算法(利用堆栈实现)相关推荐

  1. 二叉树后序遍历的非递归算法

    二叉树的后序遍历的非递归算法与二叉树的先序和中序遍历的非递归算法相比稍微复杂一点. 大致思路是:如果当前结点左右子树均为空,则可以访问当前结点,或者左右子树不均为空,但是前一个访问的结点是当前结点的左 ...

  2. 后序遍历的非递归算法(C 详细)

    后序遍历二叉树是先访问左子树,再访问右子树,最后访问根结点. 算法思想: 先沿根结点,依次入栈,直到左孩子为空 读取栈顶元素:如果其右孩子不空且未被访问过,将右子树转执行 1: 否则,栈顶元素出栈并访 ...

  3. 后序遍历的非递归算法python_二叉树后序遍历(递归与非递归)算法C语言实现...

    二叉树后序遍历的实现思想是:从根节点出发,依次遍历各节点的左右子树,直到当前节点左右子树遍历完成后,才访问该节点元素. 图 1 二叉树 如图 1 中,对此二叉树进行后序遍历的操作过程为: 从根节点 1 ...

  4. C语言 中序遍历二叉树--非递归算法

    完整代码如下: #include <stdio.h> #include <stdlib.h> #include <string.h>typedef struct B ...

  5. 后序遍历的非递归算法python_刷题系列 - Python用非递归实现二叉树后续遍历

    顺便把Python用非递归实现二叉树后续遍历也写了. 其实前序中序和后续都是针对父节点说的.比如下面这个最简单二叉树. 前序就是ABC,父节点A在前 中序就是BAC,父节点A在中间 后序就是BCA,父 ...

  6. 后序遍历的非递归算法python_Python非递归实现二叉树的后续遍历

    leetcode 145. Binary Tree Postorder Traversal 思路一: 使用一个栈stack保存经过的根结点,另一个栈flag保存每个结点的右子树是否遍历: 如果根结点存 ...

  7. 后序遍历的非递归算法python_后的解释|后的意思|汉典“后”字的基本解释

    详细字义 ◎ 后 hòu 〈名〉 (1) (会意.象人之形,施令以告四方,古之,从一口,发号者君后也.按从坐人,从口,与君同意.本义:君主,帝王) (2) 同本义 [sovereign] 后,继君体也 ...

  8. c++ stack 遍历_五分钟C语言数据结构 之 二叉树后序遍历(非递归很重要)

    五分钟C语言实现常见数据结构 今天的内容分享的是二叉树后序遍历 DP问题,欢迎关注 动态规划一篇就够了 全网最详细, 逐步理解, 万字总结 - Johngo的文章 - 知乎 https://zhuan ...

  9. 二叉树中序遍历的非递归算法

    根据二叉树的先序遍历结果创建一棵二叉树,即先创建根结点,然后再创建左子树,最后创建右子树,对于左右子树的创建也遵循根左右的原则,所以对于左右子树的创建可以递归调用本函数,此问题是典型的需要用递归算法求 ...

最新文章

  1. Java RMI详解
  2. C 多线程的互斥锁应用RAII机制
  3. 寻优秀开源项目,百万程序员为你助力!
  4. Download Microsoft Visual Studio 2010 Ultimate Trial - ISO from Official Microsoft Download Center
  5. php ngx_http_auth_basic_module,nginx认证模块ngx_http_auth_basic_module
  6. 给所有准备考网络工程师的考生的一点点建议
  7. 小,大:使用CSS fit-content
  8. 【Python项目】贪吃蛇小游戏
  9. 这两款好用的识别图片文字的软件app值得你们收藏
  10. 给screen的会话改名字
  11. 【MIS你了解多少】你现在遇到的问题都是宝贵的财富
  12. Win7系统下插入新的usb设备都提示安装驱动失败的解决方法
  13. 小白必备!Rust 编程语言入门教程
  14. [生存志] 第83节 墨子开宗称显学
  15. React组件间信息传递方式
  16. 实现百度下拉菜单实例(利用jsonp跨域请求百度数据接口)
  17. physical examination
  18. 福利放送 | 免费赠送《校园招聘实践指南》电子书
  19. ESXi通过命令行创建并直通RDM磁盘
  20. 卧槽!微信可以改彩色昵称了!!!

热门文章

  1. CentOS编译安装subversion 1.9.7
  2. 产品经理必备的软件工具 (最全最新)
  3. Swift - QQ讨论组头像的实现 (多人聊天的组合头像)
  4. Android 应用之二维码扫描登录
  5. python输出type_Python语句print(type(1/2))的输出结果是_____
  6. 启动oracle时ORA-04031错误的一种解决方法
  7. AD中PCB设计开槽
  8. 高清大图素材图片资源,你知道哪里找么?
  9. 程序员的九阳真经(转)
  10. ZMY_异步任务抽象类