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

  • 之前的博客写了递归的实现,说白了也就是不断自己调用自身,保持左根右的顺序。只需写出整体逻辑结构,程序会自己递归复杂的过程,大体即为:
void inTraverseByRecur(Tree& T)
{if(T){ inTraverseByRecur(T->lchild);cout<<T->data;inTraverseByRecur(T->rchild);}
}
  • 而非递归实现我采用了栈结构作辅助,因为中序遍历其为左根右,它本身遍历的特性可用不断的出栈进栈模拟。当我们以T为树的根结点时,要想做到中序遍历,需要以下几步:
    ①.若根结点T存在,将T压入栈中,若T->lchild为真(即T有左孩子),更新它的左孩子为根结点:即T=T->lchild,重复步骤①,直到一直往左走找不到左孩子为止(此时找到了中序序列的首结点),转至步骤②。
    ②.因为当前结点无左孩子,按照中序遍历左根右,则该结点出栈。若该结点有右孩子,则将右孩子视为根结点,转至步骤①,直到走到中序序列尽头,栈为空为止。

  • 以下为完整代码,包含了栈结构,二叉树结点结构及它们的操作函数,递归及非递归的实现函数我都放在了里面。

  • 这里有一些细节需要注意,传递指针和传递引用的区别,栈中的数据域元素存储的类型为结点结构。

#include <iostream>
#include <cstdio>
#include <cstdlib>using namespace std;#define STACK_INIT_SIZE 100   //栈的初始化容量
#define STACK_INC_SIZE 10     //栈的分配增量 typedef char ElementType;  //二叉树的数据域元素类型 /*二叉树结点结构*/
typedef struct BiTree{struct BiTree* lchild;struct BiTree* rchild;ElementType data;
}TreeNode,*Tree;typedef Tree elemType;     //栈存储的数据元素类型为二叉树结点结构 /*栈的数据结构*/
typedef struct{elemType* base;  //栈底指针 elemType* top;    //栈顶指针 int stackSize;   //当前已分配的栈总存储空间
}SqStack; void initStack(SqStack& S);             //构造空栈并初始化
void pushStack(SqStack& S,elemType data); //数据元素进栈
void popStack(SqStack& S);                //数据元素出栈
int  emptyStack(SqStack& S);              //判断栈是否为空
void createBiTree(Tree& T);               //创建并添加二叉树信息,录入方式为根左右
void inTraverseByRecur(Tree& T);          //递归方式实现中序遍历二叉树
void inTraverseByNotRecur(Tree& T,SqStack& S);  //非递归方式实现中序遍历二叉树()
elemType getTop(SqStack& S);              //返回栈顶元素 void initStack(SqStack& S)
{ S.base=(elemType*)malloc(STACK_INIT_SIZE * sizeof(elemType));if(!S.base)  exit(1);S.top=S.base;S.stackSize=STACK_INIT_SIZE;
} void pushStack(SqStack& S,elemType data)
{if(S.top-S.base>=S.stackSize) //栈满,扩充容量 {S.base=(elemType*)realloc(S.base,(S.stackSize+STACK_INC_SIZE) * sizeof(elemType));if(!S.base)  exit(1);S.top=S.base+S.stackSize; //栈顶改变S.stackSize+=STACK_INC_SIZE;}*S.top=data;S.top++;
}void popStack(SqStack& S)
{if(S.top!=S.base){S.top--;}
}int emptyStack(SqStack& S)
{//栈空则返回0 if(S.base==S.top){return 0;}else{return 1;}
}elemType getTop(SqStack& S)
{return *(S.top-1);
}   void createBiTree(Tree& T)
{ElementType ch;cin>>ch;if(ch=='#') T=NULL;else{//if(!(T=(TreeNode*)malloc(sizeof(TreeNode))))if(!(T=(Tree)malloc(sizeof(TreeNode)))){cout<<"malloc fail"<<endl;exit(0);}T->data=ch;createBiTree(T->lchild);createBiTree(T->rchild);}
}//实现递归方式的中序遍历
void inTraverseByRecur(Tree& T)
{//-+a##*b##-c##d##/e##f##if(T){inTraverseByRecur(T->lchild);cout<<T->data;inTraverseByRecur(T->rchild);}
} //实现非递归方式的中序遍历
void inTraverseByNotRecur(Tree& T,SqStack& S)
{Tree p;p=T;//若栈为空,emptyStack(S)返回为0 while(p||emptyStack(S))  //只有当结点为空,栈也为空时退出循环 {while(p)   //结点不为空时,一直找左孩子 {pushStack(S,p);p=p->lchild;}         //找不到左孩子时,若栈也不为空,则栈顶元素出栈,将栈顶元素的右孩子再作为根结点,继续找左孩子//这样持续下去最终会按照非递归的方式输出左根右 if(emptyStack(S))        {p=getTop(S);   cout<<p->data;popStack(S);p=p->rchild;}}
}int main()
{SqStack S;                 //定义栈S Tree T1;             //定义二叉树的根结点 initStack(S);           //初始化栈S createBiTree(T1);       //创建并添加二叉树信息inTraverseByRecur(T1);  //递归方式中序遍历二叉树 cout<<endl; inTraverseByNotRecur(T1,S);//非递归方式中序遍历二叉树 return 0;
}

中序遍历二叉树的非递归实现(利用栈)相关推荐

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

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

  2. (※)中序遍历二叉树的非递归算法

    在此之前,我们已经学习了中序遍历二叉树的递归算法,相信大家已经将其牢牢掌握了. 除了使用递归思想作为求解问题的钥匙,还可以借助栈来以非递归方式实现该问题的求解. 首先,我们要讨论存储二叉树结点信息的栈 ...

  3. 中序建立二叉树,非递归前序遍历二叉树

    内容: 编写程序,实现下述功能,并上机调试通过. 按中序顺序建立一棵二叉树: 用非递归方式遍历二叉树(先序),输出遍历序列. 步骤: 算法分析 采用二叉链表做存储结构,建立二叉树,借助于栈结构来实现二 ...

  4. 【数据结构笔记10】二叉树的先序、中序、后序遍历,中序遍历的堆栈/非递归遍历算法,层序遍历,确定一个二叉树,树的同构

    本次笔记内容: 3.3.1 先序中序后序遍历 3.3.2 中序非递归遍历 3.3.3 层序遍历 3.3.4 遍历应用例子 小白专场:题意理解及二叉树表示 小白专场:程序框架.建树及同构判别 文章目录 ...

  5. Morris Traversal方法遍历二叉树(非递归,不用栈,O(1)空间)——无非是在传统遍历过程中修改叶子结点加入后继结点信息(传统是stack记录),然后再删除恢复...

    先看看线索二叉树 n个结点的二叉链表中含有n+1(2n-(n-1)=n+1)个空指针域.利用二叉链表中的空指针域,存放指向结点在某种遍历次序下的前驱和后继结点的指针(这种附加的指针称为"线索 ...

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

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

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

    参考书籍:c++ 数据结构 之前提到用递归的方法实现中序遍历二叉树,但是递归会浪费大量的空间与时间.这时候我们就在想用没有一种方式能够不依赖递归去实现遍历二叉树.我们之前学过一种数据结构可以实现这种方 ...

  8. 二叉树遍历之中序遍历算法(非递归、递归)入门详解

    一.引言 二叉树的遍历常见的方法有先序遍历.中序遍历.后序遍历和层次遍历等,本文给出了C语言版本的中序遍历二叉树的非递归算法和递归算法. 中序遍历的原理很简单,也就是把树根的访问放在中间.访问结点的次 ...

  9. 剑指offer之中序打印二叉树(非递归实现)

    1 问题 中序打印二叉树(非递归实现),比如二叉树如下 /* 2* 3 5 * 1 4 2 3 * 3 2 1 5 1 4 2 3 中序:按左中右来打印二叉树,结果如下 3 1 2 3 1 4 5 2 ...

最新文章

  1. elasticsearch批量修改,批量更新某个字段
  2. njust 1927 谁才是最强战舰!(anti-nim博弈论)
  3. squid服务配置(正向、反向代理)
  4. Flink : Cannot find compatible factory for specified execution.target (=local)
  5. 001 python接口 get请求
  6. python用pyecharts画柱状图_小白学Python(13)——pyecharts 绘制 柱状图/条形图 Bar
  7. 黄色量能通达信指标公式!没有未来函数,不加密的副图指标!
  8. 聊聊docker【二】基本命令
  9. python实训总结泰坦尼克号重建_Python之泰坦尼克号生存率分析
  10. 干货:8266在3d打印机上的使用
  11. 创始人和VC疯狂撕逼,究竟所为何事?
  12. 财务自由到底是啥感觉啊...
  13. 火狐3本月17日发布 与IE 8设计理念完全不同
  14. 成长计划校园极客秀|基于OpenHarmony的智能阳台
  15. KALI LINUX渗透测试学习笔记
  16. Android7 WIFI系统 PNO机制流程详解和隐藏BUG修改
  17. APP性能测试--帧率测试
  18. 32位(x86)和64位(x64)
  19. 安卓Android sqllite实现保存数据和读数据
  20. 读书笔记 -- 推荐系统实践(1)

热门文章

  1. 重复测量数据多重填补 SAS code
  2. android 关机界面修改,修改Android关机界面
  3. gym:Problem B Bless You Autocorrect!(字典树+最短路)
  4. 微信小程序海报生成图片合成工具类
  5. xsd 和 wsdl
  6. 如何在sqlserver中写存储过程
  7. The_Last_Geass
  8. linux一级目录全解
  9. 4 ARM PEG20K MAL
  10. Cy5-MAL,Cy5-马来酰亚胺,1437796-65-0,1437872-46-2