非递归遍历二叉树

二叉树的三种遍历非递归实现 二叉树遍历实现 阅读详情

1.先序遍历

从递归说起

  1. void preOrder(TNode* root)
  2. {
  3.     if (root != NULL)
  4.     {
  5.         Visit(root);
  6.         preOrder(root->left);
  7.         preOrder(root->right);
  8.     }
  9. }

递归算法非常的简单。先访问跟节点,然后访问左节点,再访问右节点。如果不用递归,那该怎么做呢?仔细看一下递归程序,就会发现,其实每次都是走树的左分支(left),直到左子树为空,然后开始从递归的最深处返回,然后开始恢复递归现场,访问右子树。

其实过程很简单:一直往左走 root->left->left->left...->null,由于是先序遍历,因此一遇到节点,便需要立即访问;由于一直走到最左边后,需要逐步返回到父节点访问右节点,因此必须有一个措施能够对节点序列回溯。有两个办法:
1.用栈记忆:在访问途中将依次遇到的节点保存下来。由于节点出现次序与恢复次序是反序的,因此是一个先进后出结构,需要用栈。
使用栈记忆的实现有两个版本。第一个版本是模拟递归的实现效果,跟LX讨论的,第二个版本是直接模拟递归。
2.节点增加指向父节点的指针:通过指向父节点的指针来回溯(后来发现还要需要增加一个访问标志,来指示节点是否已经被访问,不知道可不可以不用标志直接实现回溯?想了一下,如果不用这个标志位,回溯的过程会繁琐很多。暂时没有更好的办法。)

(还有其他办法可以回溯么?)
这3个算法伪代码如下,没有测试过。

先序遍历伪代码:非递归版本,用栈实现,版本1

  1. // 先序遍历伪代码:非递归版本,用栈实现,版本1
  2. void preOrder1(TNode* root)
  3. {
  4.     Stack S;
  5.     while ((root != NULL) || !S.empty())
  6.     {
  7.         if (root != NULL)
  8.         {
  9.             Visit(root);
  10.             S.push(root);       // 先序就体现在这里了,先访问,再入栈
  11.             root = root->left;  // 依次访问左子树
  12.         }
  13.         else
  14.         {
  15.             root = S.pop();     // 回溯至父亲节点
  16.             root = root->right;
  17.         }
  18.     }
  19. }

preOrder1每次都将遇到的节点压入栈,当左子树遍历完毕后才从栈中弹出最后一个访问的节点,访问其右子树。在同一层中,不可能同时有两个节点压入栈,因此栈的大小空间为O(h),h为二叉树高度。时间方面,每个节点都被压入栈一次,弹出栈一次,访问一次,复杂度为O(n)

 

 先序遍历伪代码:非递归版本,用栈实现,版本2
  1. // 先序遍历伪代码:非递归版本,用栈实现,版本2
  2. void preOrder2(TNode* root)
  3. {
  4.     if ( root != NULL)
  5.     {
  6.         Stack S;
  7.         S.push(root);
  8.         while (!S.empty())
  9.         {
  10.             TNode* node = S.pop(); 
  11.             Visit(node);          // 先访问根节点,然后根节点就无需入栈了
  12.             S.push(node->right);  // 先push的是右节点,再是左节点
  13.  &
二叉树非递归遍历和层次遍历详解 二叉树非递归遍历非递归的后序遍历二叉树 //非递归的后续遍历二叉树 void HXprint(Tree *tree){ Stack s = initStack(); //初始化一个下面使用的栈 treeNode *p = tree; //新建一个遍历指针 treeNode *r=NULL; //辅助变量 cout<<"-------"<<endl; while(p||!isEmpty(s)){ //当遍历变量和栈同时为空时 表示遍历完成 阅读详情

相关推荐

二叉树非递归遍历遍历、中根遍历、后根遍历

二叉树非递归遍历 二叉树的三种遍历方式也可以通过非递归的方法借助栈来实现。 通过控制节点的出栈和入栈后顺序来实现对树的不同方式的遍历非递归遍历二叉树 当栈不为空或者当前节点为不为空,执行操作: 从根节点开始,依次访问树中最左端的节点并入栈,当节点为空停止入栈。 取栈顶元素为当前节点并出栈,如果当前节点有右子树,则遍历其右子树。 void PreorderPrint(...

SanFancsgo的博客 8308

C++—非递归【循环】遍历二叉树(前序,中序,后序)思路讲解+代码实现

使用循环,借助栈和顺序表来实现二叉树的三种遍历方式,结尾处附上源代码链接。

Javaxaiobai的博客 3028

电路仿真软件PSIM简介

PSIM的基本使用操作...

qq_55203246的博客 7032

二叉树遍历的一些非递归算法

非递归二叉树遍历算法C语言

m0_66120913的博客 1万+

二叉树遍历(非递归)

遍历二叉树, 是指按一定的规则和顺序访问二叉树的所有结点, 使每一个结点都被访问一次, 而且只被访问一次.也可以是NRL, 因为这两种遍历方法都是访问根结点, 所以没有区别, 掌握其中一种, 另一种也随之掌握.BFS: 是指沿着二叉树的宽度优遍历二叉树的结点, 即从上到下从左到右逐层遍历二叉树的结点.由于二叉树是非线性结构, 因此, 二叉树遍历实质上是将二叉树的各个结点排列成一个线性序列.层序遍历就是根据二叉树的结构从上到下从左到右逐层遍历二叉树的结点.给你一棵二叉树的根节点。

m0_61433144的博客 9104

数据结构实验6----二叉树序遍历非递归算法

二叉树序遍历非递归算法:结点要入两次栈,出两次栈;为了区别同一个结点的两次出栈,设置标志flag,当结点进、出栈时,其标志flag也同时进、出栈。

qq_60737285的博客 902

二叉树非递归遍历算法

1.序遍历 遍历顺序:根节点—>左孩子—>右孩子 算法过程: 从当前节点开始遍历: 若当前节点存在,就存入栈中,并访问左子树; 直到当前节点不存在,就出栈,并通过栈顶节点访问右子树; 不断重复12,直到当前节点不存在且栈空。 过程如下: 注意:因为采用的是栈操作,根据栈“入后出”的特点,在进栈之前就要访问节点的元素 上图访问顺序为:12453 代码实现如下: //1...

朱家小旺 1896

详解二叉树非递归遍历

本文转载自:http://blog.csdn.net/zhangxiangdavaid/article/details/37115355 前言   对于二叉树的递归遍历比较简单,所以本文主要讨论的是非递归版。其中,中序遍历非递归写法最简单,后序遍历最难。 节点的定义: //Binary Tree Node typedef struct node { int data; ...

编程随笔与杂谈 10万+

二叉树非递归遍历

二叉树非递归遍历 二叉树是一种非常重要的数据结构,很多其它数据结构都是基于二叉树的基础演变而来的。对于二叉树,有前序、中序以及后序三种遍历方法。因为树的定义本身就是递归定义,因此采用递归的方法去实现树的三种遍历不仅容易理解而且代码很简洁。而对于树的遍历若采用非递归的方法,就要采用栈去模拟实现。在三种遍历中,前序和中序遍历非递归算法都很容易实现非递归序遍历实现起来相对来说要难一点。 ​ 三种遍历方式访问节点的顺序是一致的,不同之处在于,有的遍历流程把访问到的节点暂存起来,达成某种条件后再将节点输出。

qq_43169752的博客 1万+

二叉树遍历非递归算法

•三种遍历​ • 序遍历: 根节点–>左子树–>右子树​ • 中序遍历: 左子树–>根节点–>右子树​ • 后序遍历: 左子树–>右子树–>根节点•两类算法​ • 递归算法(具体看我上一篇文章)​ ♥直观,易读​ ♥效率低下​ • 非递归算法​ ♥ 如果一个算法可以使用递归或循环来进行完成,在不影响代码阅读的情况下,可以使用循环,来降低复杂度。下面介绍二叉树遍历,把用。

qq_57484399的博客 6167

伪代码二叉树查找java_二叉树的各种遍历实现伪代码

本文的copyleft归gfree.wind@gmail.com所有,使用GPL发布,可以自由拷贝,转载。但转载请保持文档的完整性,注明原作者及原链接,严禁用于任何商业用途。作者:gfree.wind@gmail.com博客:linuxfocus.blog.chinaunix.net最近需要复习一下基础算法,今天来个二叉树的几种遍历方式的伪代码吧。其中每种遍历方式都分为递归和非递归两种。下面的代...

weixin_33617670的博客 1030

非递归实现二叉树遍历(附c++完整代码)

序、中序和后序遍历过程:遍历过程中经过结点的路线一样,只是访问各结点的时机不同。 从图中可以看到,前序遍历在第一次遇见元素时输出,中序遍历在第二次遇见元素时输出,后序遍历在第三次遇见元素时输出。 非递归算法实现的基本思路:使用堆栈 一、前序遍历 1、递归实现 遍历过程为: 访问根结点; 序遍历其左子树; 序遍历其右子树。 void ProOrderTraverse(BiTree tre...

桑凯旋的博客 2万+

(利用栈实现非递归)Leetcode 二叉树的中序遍历 java

给定一个二叉树,返回它的中序遍历。 示例: 输入: [1,null,2,3] 1 \ 2 / 3 输出: [1,3,2] 法一 递归法 理解: List.addAll() 成功 显示详情 执行用时 :2 ms, 在Binary Tree Inorder Traversal的Java提交中击败了49.67% 的用户 内存消耗 :3...

keliwahada 1132

数据结构非递归实现二叉树序遍历

非递归实现二叉树序遍历

每天进步一点丶的博客 4489

二叉树的前序遍历、中序遍历、后序遍历、层序遍历的时间复杂度和空间复杂度

非递归版: 由于不管是序遍历还是中序遍历以及后序遍历,我们都需要利用一个辅助栈来进行每个节点的存储打印,所以每个节点都要进栈和出栈,不过是根据那种遍历方式确定节点的进栈顺序,所以时间复杂度为O(n),同样空间复杂度也为O(n),n为结点数。 层序遍历是通过队列来进行每个节点的存储打印的,所以时间复杂度和空间复杂度也与前三种遍历方式一样。 递归版: 空间复杂度与系统堆栈有关,系统栈需要记住每个节点...

algsup 4万+

5.3二叉树遍历和线索二叉树

一、二叉树序遍历 算法复杂度为:O(h+1) h是二叉树的高度,1是最后的叶子节点有左右两个空结点,也需要将其压入栈。 二、二叉树层次遍历 结点出队并访问该节点,其左右孩子入队 对于E来说,其没有左右孩子,访问完E之后不会有结点入队 访问一个节点,存的是其指针而不是结点 三、由遍历序列构造二叉树 可以由以上三种方法唯一确定二叉树可以根据前序遍历发现A是根节点 ①首序遍历=>D是根节点, ②再看中序遍历可得D的左侧是其左子树,右侧是右子树。.

qq_43667537的博客 483

移动支付APP(仿支付宝)

Toast.makeText(PayActivity.this, "支付失败:" + payResponse.getMsg(), Toast.LENGTH_SHORT).show();Toast.makeText(PayActivity.this, "支付失败:" + t.getMessage(), Toast.LENGTH_SHORT).show();Toast.makeText(PayActivity.this, "支付失败", Toast.LENGTH_SHORT).show();

寒寒豆豆软件公司的博客 110

McgsPro-驱动文件-汇川H5U以太网-7.0.1.8

McgsPro_驱动文件_汇川H5U以太网_7.0.1.8

上一篇: C++构造和析构
下一篇: 非递归遍历二叉树
kofsky
博客等级 码龄22年 176粉丝 134原创
评论 30
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值