二叉树中序非递归遍历算法实现

大家好,我是逝去的粒子,从今天起,我将尝试着数据结构从0开始学习分享,此篇文章作为试验,一方面可以为自己做笔记防止遗忘,另一方面希望可以帮助大家。不废话,正式开始。

1.第一步,我们需要先序递归创建二叉树,栈,以及栈的基础方法,因为上述这些不是今天的重点且网上有很多讲解,我就不重复造轮子了,代码如下:

#include "stdio.h"
#include "stdlib.h"
#define MaxSize 50
typedef int ElemType;//树的定义
typedef struct BiTNode{int data;struct BiTNode *lchild,*rchild;
}BiTNode,*BiTree;//栈的定义
typedef struct{BiTree data[MaxSize];int top;
}SqStack;//初始化
void InitStack(SqStack &s){s.top=-1;
}//判断栈空
bool StackEmpty(SqStack &s){if(s.top==-1)return true;elsereturn false;
}   //进栈
bool Push(SqStack &s,BiTree x){if(s.top==MaxSize-1){return false;}s.data[++s.top]=x;return true;
}//出栈
BiTree Pop(SqStack &s,BiTree x){if(s.top==-1){return false;}x=s.data[s.top--];return x;
}//读取栈顶元素
bool GetTop(SqStack &s){BiTree x;if(s.top==-1){return false;}x=s.data[s.top];printf("%c",x->data);return true;
}
//创建二叉树,递归创建,默认先序输入
void CreateBiTree(BiTree &T){char c;scanf("%c",&c);if(c=='#'){T=NULL;}else{T=(BiTree)malloc(sizeof(BiTNode));T->data=c;CreateBiTree(T->lchild);CreateBiTree(T->rchild);}
}

2.第二步:假设我们先序遍历输入:12#46###3#5##,(#表示空节点),如下创建了一个这样的二叉树:

3.第三步:递归先序遍历,简单来说就是始终坚持先左后中再右,代码如下:

//中序遍历--递归
void InOrder(BiTree T){if(T!=NULL){InOrder(T->lchild);printf("%c",T->data);InOrder(T->rchild);}
}
简单来说就是将树T的指针传过来,依次遍历,有的人传的是指针的地址,效果都一样

--------------------------------接下来就是今天的重点了:非递归中序-------------------------

4.第4步非递归中序遍历算法思想-->借助栈,先有一个工作指针p,让其从头节点依次扫描左节点,并将扫描到的节点依次进栈,如果扫描的左节点为空了时,从栈中弹出一个节点,此时显然弹出的这个节点及其他的左子树都已经被访问过了,我们再使用p继续访问此节点的右节点,将其进栈,然后继续右孩子节点的所有左孩子,不停的迭代,直到所有节点全部访问过,并且栈为空。根据此思想,编写如下代码:

//中序遍历--非递归
void InOrder2(BiTree T){SqStack s;InitStack(s); //初始化栈BiTree p=T,a;        //遍历指针pwhile(p||!StackEmpty(s)){if(p){Push(s,p);p=p->lchild;}else{GetTop(s);    //在p出栈之前先查看a=Pop(s,p);     //出栈,a为接收出栈的p节点p=p->rchild;}}
}
1.首先初始化栈s,我用的是顺序栈,有能力的同学可以尝试着用链栈。
2.创建工作指是针p和a,其中p指向树T,也就是p指向节点1。
3.进入循环(p不为空或者栈s不为空时)执行循环体:做判断:如果工作指针p不为空,此时p指向的节点1进栈,p继续指向左子树指向了节点2,继续将2进栈,由于节点2没有左子树,所以进入else语句,出栈之前输出节点值,那么此时输出的就是2,并将节点2弹出栈,再寻找节点2的右节点,进入if语句,就这样不断迭代。

好了,现在我们看似代码还是比较ok的,因为我本身小白,没办法,此时,运行试试看。

果然没辜负我,又出错了,递归中序遍历能够正常实现,但非递归却只出现了一个数字2,再就没反应了,这是为什么。

5.第5步:调试阶段
为非递归这个函数添加一个断点,进行一步步调试,查看栈s以及p指针的变化。

直到有错误提示

此时我们发现了一个大问题,p指针的左右孩子都是为空,说明此时的p就是一个空指针,而且p的值为0x000000,有bug就解决,我发现,导致p错误的原因是当从栈中弹出一个节点时,我用的p指针已经不再是指向弹出那个节点的,而是指向了一个空节点,所以程序猜到else语句,对不对,那么原先写的p=p->lchild毫无疑问是错误的,此时,我想到用一个指针a来接收弹出的节点,然后将a赋给p,然后p代表当前弹出节点并继续访问其右节点。
如果有疑问的话,建议照着刚写的代码画着图实际演练一遍,或可以联系我。

//中序遍历--非递归
void InOrder2(BiTree T){SqStack s;InitStack(s); //初始化栈BiTree p=T,a;        //遍历指针pwhile(p||!StackEmpty(s)){if(p){Push(s,p);p=p->lchild;}else{GetTop(s);    //在p出栈之前先查看a=Pop(s,p);     //出栈,a为接收出栈的p节点p=a;p=p->rchild;}}
}


成功解决,当遇到bug时,要学会去调试代码,当然调试的前提是你必须要手动的会描述一个算法过程。今天的试验分享就到这,后面会不定期分享我会的数据结构,第一次写的不好请见谅。

数据结构之---非递归中序遍历二叉树相关推荐

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

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

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

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

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

    中序遍历二叉树(递归) void inOrder(BT* root) {if (root == NULL)return;inOrder(root->lchild);cout << & ...

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

    算法 非递归先序遍历二叉树总结(3种方法) @author:Jingdai @date:2020.12.03 传送门 非递归中序遍历二叉树 非递归后序遍历二叉树 递归先序遍历二叉树非常的简单,但是面试 ...

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

    算法 非递归后序遍历二叉树总结(2种方法) @author:Jingdai @date:2020.12.04 传送门 非递归先序遍历二叉树 非递归中序遍历二叉树 方法1 非递归用栈来辅助遍历,后序遍历 ...

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

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

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

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

  8. 不用栈实现二叉树非递归中序遍历

    偶尔看到这样一个问题: 有个二叉树,每个节点除了左右指针外,还有一个指向父节点的指针. 要求不用递归,中序遍历这棵树.另要求空间复杂度是O(1). 空间复杂度为O(1),摆明就是不让用堆栈模拟递归,所 ...

  9. LeetCode:二叉树的非递归中序遍历

    第一次动手写二叉树的,有点小激动,64行的if花了点时间,上传leetcode一次点亮~~~ 1 /* inorder traversal binary tree */ 2 #include < ...

最新文章

  1. Linux上用户执行命令记录
  2. mysql安全性实验心得_mysql安全小结
  3. Java基础之多态深入解析
  4. c调用python第三方库_用 Python ctypes 来调用 C/C++ 编写的第三方库
  5. matlab区分卷积和相关
  6. [论文阅读] Learning Without Forgetting
  7. 【ASP.NET学习笔记一】ASP.NET页面传参总结
  8. 2022电工杯B题思路模型分析
  9. java scene_JavaFX中场景(Scene)的意义是什么?
  10. python谁的教程好贴吧_python深挖65万人的明星贴吧,探究上万个帖子的秘密
  11. 【Android,Kotlin】自定义弹框的简单写法Demo
  12. 判断是否为 retina屏幕
  13. F: Shattered Cake
  14. 用户上传用户头像至服务器
  15. 单月涨粉30w+,他们掌握引流法宝,小红书1月创作趋势是什么?
  16. Android开发唯一的出路:进阶学习,android实战pdf
  17. Tableau实现跑道图
  18. 背包问题求解(数据结构课设)
  19. 华为数通 软开2021实习生 业务主管面 (已通过)
  20. 【信息保护论】Ch2. 加密与解密: 密码学历史中出现过的密码学技术

热门文章

  1. Flink重启策略和故障恢复策略
  2. 小米Note如何?看看老外是怎么说的
  3. win7任务管理器是灰色win7任务管理器按不出来
  4. 机器学习-随机森林总结
  5. Ffmpeg快慢镜头,操作音视频
  6. java求两个数的平均值-这么简单我竟然不会?
  7. 小米手机root后过软件检测
  8. 长时间久坐危害竟然这么大,这4项检查,男性朋友一定要定期查
  9. python调用gpu amd_python-将Keras和Tensorflow与AMD GPU一起使用
  10. 谈谈浏览器的缓存过期时间