数据结构之---非递归中序遍历二叉树
二叉树中序非递归遍历算法实现
大家好,我是逝去的粒子,从今天起,我将尝试着数据结构从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时,要学会去调试代码,当然调试的前提是你必须要手动的会描述一个算法过程。今天的试验分享就到这,后面会不定期分享我会的数据结构,第一次写的不好请见谅。
数据结构之---非递归中序遍历二叉树相关推荐
- 非递归中序遍历二叉树总结(2种方法)
算法 非递归中序遍历二叉树总结(2种方法) @author:Jingdai @date:2020.12.03 传送门 非递归先序遍历二叉树 非递归后序遍历二叉树 方法1 先序遍历是第一次遇到该节点遍历 ...
- 非递归前序遍历二叉树,非递归中序遍历二叉树,非递归后续遍历二叉树
import java.util.Stack;public class Front {//非递归前序遍历public void front(TreeNode node) {Stack<TreeN ...
- 非递归中序遍历二叉树
中序遍历二叉树(递归) void inOrder(BT* root) {if (root == NULL)return;inOrder(root->lchild);cout << & ...
- 非递归先序遍历二叉树总结(3种方法)
算法 非递归先序遍历二叉树总结(3种方法) @author:Jingdai @date:2020.12.03 传送门 非递归中序遍历二叉树 非递归后序遍历二叉树 递归先序遍历二叉树非常的简单,但是面试 ...
- 非递归后序遍历二叉树总结(2种方法)
算法 非递归后序遍历二叉树总结(2种方法) @author:Jingdai @date:2020.12.04 传送门 非递归先序遍历二叉树 非递归中序遍历二叉树 方法1 非递归用栈来辅助遍历,后序遍历 ...
- 无栈非递归中序遍历非线索化二叉树
试设计一个非递归算法,按中根顺序遍历非线索二叉树,但不得用任何辅助. 在执行算法期间,允许改变LLINK和RLINK的值. 如何不用辅助栈非递归遍历二叉树呢? 这里给出了一个比较方便的算法,其基本思路 ...
- 二叉树非递归中序遍历
二叉树的中序遍历 为什么把中序遍历放在最前面呢,因为在非递归遍历中,这个是最简单也是最容易理解的,所以放在第一个的位置. 中序遍历的递归算法很简单,但是想要非递归的实现,就要用到栈这个数据结构, 那么 ...
- 不用栈实现二叉树非递归中序遍历
偶尔看到这样一个问题: 有个二叉树,每个节点除了左右指针外,还有一个指向父节点的指针. 要求不用递归,中序遍历这棵树.另要求空间复杂度是O(1). 空间复杂度为O(1),摆明就是不让用堆栈模拟递归,所 ...
- LeetCode:二叉树的非递归中序遍历
第一次动手写二叉树的,有点小激动,64行的if花了点时间,上传leetcode一次点亮~~~ 1 /* inorder traversal binary tree */ 2 #include < ...
最新文章
- php广告轮播效果,使用swiper组件实现轮播广告效果
- MobPush精准把握用户的使用时间
- responsebody如何将数据转换成json的_干货分享:如何用Retrofit直接获得Json数据(字符串)...
- c语言cnn实现ocr字符,端到端的OCR:基于CNN的实现
- SAP Spartacus cxOutlet 里的 templatesRefs 的填充逻辑
- if sql语句_SQL IF语句介绍和概述
- 数据湖产业生态联盟会员权益
- linux下仿真流体计算软件,【流体】| 10个目前流行的CFD仿真软件,你了解几个?...
- 线性规划问题的模型建立与求解
- 无法ping通别的计算机名,解决主机无法ping通问题
- php和mysql web开发 目录_PHP和MySQL Web开发(原书第5版)简介,目录书摘
- 5.Linux系统中解压缩详解
- 动态代理实例——增强Waiter接口
- Vulnhub靶机系列:SecTalks: BNE0x03 - Simple
- tekton入门 - piplinerun
- 如何用Python投机倒把几天“暴富”
- 【西安电子科技大学】考研初试复试资料分享
- 成功改造企业文化的八项原则
- [数值计算-5]:一元二次非线性方程求解 - 解析法直接求解
- mediapipe之人脸特征点468检测