偶尔看到这样一个问题:

有个二叉树,每个节点除了左右指针外,还有一个指向父节点的指针。
要求不用递归,中序遍历这棵树。另要求空间复杂度是O(1).

空间复杂度为O(1),摆明就是不让用堆栈模拟递归,所以想了想思路,也请教过好几个朋友,大家都基本想法都差不多,由于有指向父节点的指针,必定可以回溯,从而可以不需要堆栈来做记录.

但是实现起来,却发现很多细节需要完善,比如遍历的终止条件,现在我是用预先遍历到最后一个右子树,用这个指针作为终止条件.

昨天大体实现了一下.

贴出来,期待达人改进.

/*思路: 关于终止条件:中序遍历终止于最后的rchild,只能先遍历一遍,将该节点作为终止条件。 对遍历时候的 cur节点设置一个状态(0,1,2) 0标识其左,右节点情况尚未处理 1标识其左节点被处理(包括左节点不存在的情况) 2标识从右节点返回(包括右节点不存在的情况) 3种状态的判断用(post->parent->lchild == post)这样的方法判断。 */ void inorder_norecursive(LinkTree *root) { LinkTree * cur=root, * post, *fin; int cur_state = 0; while(cur != NULL) //查找终止条件 { post = cur; cur = cur->rchild; } fin = post; cur = root; post = NULL; printf("fin data :%d /n",fin->data); while( !(cur == fin && cur_state >=1) ) { while(cur != NULL && cur->lchild != NULL && cur_state != 2) //搜索:每次遍历,当前状态清零,找到可以打印的点,从右节点返回不应该继续向下遍历 { cur_state = 0; cur = cur->lchild; } if( (cur == NULL && cur_state == 1) || cur_state == 2) //返回:右节点为空,返回的情况或者从右节点返回 { cur = post; if(cur->parent->lchild == cur) cur_state = 1; else if(cur->parent->rchild == cur) cur_state = 2; cur = cur->parent; } if( cur->lchild == NULL && cur_state == 0) cur_state = 1; post = cur; //post针对cur遍历到NULL时候返回,记录有效节点 if( cur_state == 1) //中序打印 { printf(" %d ",cur->data); if(cur == fin) //打印最后一个,显式退出 break; } else if(cur_state == 2) //节点的2个子节点已被处理,向上返回 continue; if(cur->rchild == fin) //如果是fin节点的父节点,提前设置cur_state状态,防止while退出 cur_state = 0; cur = cur->rchild; } }

关于普通的中序非递归写法,可以参考这里:

http://blog.csdn.net/fuzhufang/archive/2009/03/08/3969375.aspx

不用栈实现二叉树非递归中序遍历相关推荐

  1. 二叉树非递归中序遍历

    二叉树的中序遍历 为什么把中序遍历放在最前面呢,因为在非递归遍历中,这个是最简单也是最容易理解的,所以放在第一个的位置. 中序遍历的递归算法很简单,但是想要非递归的实现,就要用到栈这个数据结构, 那么 ...

  2. 数据结构之---非递归中序遍历二叉树

    二叉树中序非递归遍历算法实现 大家好,我是逝去的粒子,从今天起,我将尝试着数据结构从0开始学习分享,此篇文章作为试验,一方面可以为自己做笔记防止遗忘,另一方面希望可以帮助大家.不废话,正式开始. 1. ...

  3. 非递归中序遍历二叉树总结(2种方法)

    算法 非递归中序遍历二叉树总结(2种方法) @author:Jingdai @date:2020.12.03 传送门 非递归先序遍历二叉树 非递归后序遍历二叉树 方法1 先序遍历是第一次遇到该节点遍历 ...

  4. 非递归前序遍历二叉树,非递归中序遍历二叉树,非递归后续遍历二叉树

    import java.util.Stack;public class Front {//非递归前序遍历public void front(TreeNode node) {Stack<TreeN ...

  5. 二叉树非递归后序遍历算法(C语言)

    二叉树非递归后序遍历算法(C语言) 二叉树后序遍历的规律:左右根 后序非递归遍历中,访问根(子根)结点有两种情况 ①:遍历完左子树,需要遍历右子树,需要从栈中访问最顶上的根(子根)结点从而得到右子树的 ...

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

    与正常的非递归中序遍历算法不同于两点: 一  比正常的中序遍历算法多了对数据元素的标记. 在压数据元素入栈(标记记为0,用来表示访问了其左子树)时标记, 还有访问完左子树利用gettop()获取双亲通 ...

  7. 二叉树非递归先序遍历

    二叉树的递归先序遍历很简单,假设二叉树的结点定义如下: 1 struct BinaryTreeNode 2 { 3 int m_nValue; 4 BinaryTreeNode* m_pLeft; 5 ...

  8. 二叉树非递归后序遍历算法的一种简单思路

    首先从简单的例子开始 1 2 3 上图二叉树的后序遍历序列是"231", 颠倒一下就是"132", 而其前序遍历是"123" 有什么发现? ...

  9. 无栈非递归中序遍历非线索化二叉树

    试设计一个非递归算法,按中根顺序遍历非线索二叉树,但不得用任何辅助. 在执行算法期间,允许改变LLINK和RLINK的值. 如何不用辅助栈非递归遍历二叉树呢? 这里给出了一个比较方便的算法,其基本思路 ...

最新文章

  1. 2021年人工智能和机器学习的五大趋势
  2. poj 2515 差分序列,排列组合
  3. 更改idea控制台输出字体
  4. 模拟撞击_模玩资讯:EPOCH 汽车撞击测试用模拟假人与实验车辆
  5. 《计算机组成原理》_学习笔记(二)
  6. 【数据库】Mysql的CONCAT()函数拼接字符串
  7. axios流输出excel
  8. 计算机html基础试题与答案,2019年大学计算机基础试题题库及答案.docx
  9. SQLMAP 注入教程
  10. 数学建模之蒙特卡罗模型
  11. 3. Zigbee应用程序框架开发指南 - 应用程序框架目录结构
  12. badboy设置中文_badboy基本操作
  13. 本世纪最好的NSA!
  14. 安卓逆向小案例——阿里系某电影票务APP加密参数还原-Unidbg篇
  15. app内接入高德地图常用设置及工具方法整理
  16. PCA-APCA-MLR
  17. map集合---------今日份下饭菜,妈妈再也不用担心我饿肚子了,学好List, Set,与Map,装的下,世界就是你的
  18. 教你淘宝店铺如何做推广!
  19. Oracle高级函数:rank over partition by
  20. Java-虚拟机原理

热门文章

  1. 在字节跳动实习30天的4点成长感受
  2. dragtoresize什么意思_drag to是什么意思
  3. NLP教程笔记:GPT 单向语言模型
  4. Cognex Mobile Barcode SDK for iOS
  5. v7000存储硬盘离线如何恢复数据
  6. 零伽壹|多地印发涵盖区块链技术的发展实施意见
  7. nes转php,PHP4 ORACLE8i NES3.6 for Solaris2.6编译和远程连接指南(转)
  8. 学生学籍管理系统------上☞(设计报告篇)
  9. 【Python Brain】SNN脉冲神经网络开源模拟器 The Brian Simulator 仿真指南
  10. Premiere 2.0至Premiere CS5.5高清插件MainConcept(已破解)提供115网盘下载地址