根据二叉树的先序遍历结果创建一棵二叉树,即先创建根结点,然后再创建左子树,最后创建右子树,对于左右子树的创建也遵循根左右的原则,所以对于左右子树的创建可以递归调用本函数,此问题是典型的需要用递归算法求解的问题,关于递归算法不了解的可以看我上一篇博文http://t.csdn.cn/YDhB4

在写代码的过程中可以加入一些提示性的内容,让用户知道该怎么进行输入结点元素的值 。算法实现代码:


//使用递归算法,创建二叉树
void F_CreateBitree(Bitree root)
{//先序创建,遵循先创建根结点,再创建左子树最后在创建右子树,创建左右子树的时候递归调用此算法//输入根结点元素的值printf("请输入根结点的值\n");scanf("%c", &(root->data));getchar();//递归出口是输入#if (root->data == '#'){return;}//创建根结点元素的值//创建左子树,左子树递归调用本函数printf("请输入%c的左子树的根结点的值\n",root->data);root->lchild = (Bitree)malloc(sizeof(BitreeNode));F_CreateBitree(root->lchild);//创建右子树,右子树递归调用本函数printf("请输入%c的右子树的根节点的值\n",root->data);root->rchild = (Bitree)malloc(sizeof(BitreeNode));F_CreateBitree(root->rchild);if ((root->lchild)->data == '#'){root->lchild = NULL;}if ((root->rchild)->data == '#'){root->rchild = NULL;}}

创建完成该二叉树之后要对该二叉树进行中序遍历,下面实现二叉树的中序遍历的算法是非递归的,用到了栈的知识,我在上一篇博文写了使用递归算法实现先序遍历,中序遍历,后序遍历二叉树的算法,感兴趣的话可以去看看http://t.csdn.cn/NLff5

利用栈来实现二叉树的中序遍历的非递归算法,算法思路:

中序遍历的思想就是先遍历左子树,然后访问根结点,最后遍历右子树,对于左右子树的遍历也遵循左根右的原则,所以其思想就是沿着左子树深入,直到到达左子树为空的结点位置,此时将此节点的元素进行输出,即进行出栈操作,然后再访问该节点的右子树,访问完成右子树之后需要返回该结点的上一个结点 ,其实这一步操作是通过退栈操作来完成的。以下是实现算法的源代码:

void MiddleOrderTraverse(Bitree root,Ls mystack)
{//中序遍历,先遍历左子树,在遍历根结点,最后遍历右子树,对左右子树的遍历也遵循左根右的原则//利用栈来实现中序遍历的非递归算法Bitree m = root;//先判断二叉树是不是为空if (!root){return;}while (1){//根结点入栈Bitree temp;if (m){InsertStack(mystack, m);m = m->lchild;                        //先沿着左子树深入直到到达左子树为空的结点}else{temp = PopStack(mystack);               //当到达左子树为空的结点,将当前结点元素进行退栈,即输出当前结点的值,然后继续访问当前节点的右子树。//整个过程是不断重复地过程即沿着左子树深入直至为空,然会输出当前栈顶元素的值,然会返回上一结点元素,然后继续访问当前节点的右子树,所以有后深入的先返回的特性,//可以运用站的特性实现此算法,而实现返回上一个结点是通过退栈这一操作完成的printf("%c\t", temp->data);m = temp->rchild;}if ((mystack->top==mystack->base) && m == NULL){break;}}}

既然要用到栈,那么就要先实现栈的定义,以及定义实现相关操作的接口,站的定义以及相关操作的实现的源代码如下:

//定义链栈结点
typedef struct LinkStackNode
{Bitree node;struct LinkStackNode* next;
}LinkStackNode,*LsNode;//定义链栈
typedef struct Linkstack
{LsNode top;                 //定义栈顶指针,栈顶是允许插入和删除的一端LsNode base;                //定义栈底指针,是不允许进行插入和删除元素的一端
}LinkStack,*Ls;//创建一个空栈
void InitStack(Ls mystack);//向栈中插入元素e
void InsertStack(Ls mystack, Bitree e);                 //向栈中插入元素不存在栈满问题但存在栈空问题,只能在栈顶处插入元素//若栈不空则删除栈顶元素,并将栈顶元素的值作为函数返回值返回
Bitree PopStack(Ls mystack);void InitStack(Ls mystack)
{mystack->top = mystack->base = (LsNode)malloc(sizeof(LinkStackNode));mystack->base->next = NULL;printf("创建空栈成功\n");
}void InsertStack(Ls mystack, Bitree e)
{LsNode p = (LsNode)malloc(sizeof(LinkStackNode));if (!p){printf("ERROR:申请内存失败\n");return;}p->node = e;p->next = mystack->top;mystack->top = p;
}Bitree PopStack(Ls mystack)
{if (mystack->top->next != NULL){LsNode temp;Bitree t;temp = mystack->top;t = temp->node;mystack->top = mystack->top->next;free(temp);return t;}return NULL;}

完整程序源代码以及运行效果截图

程序源代码:

//根据二叉树的先序遍历结果来创建一棵二叉树,并对其进行先序,中序,后序遍历输出,遍历时用到栈的知识以实现非递归算法;#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include<stdlib.h>//定义树节点typedef struct BitreeNode
{char data;        //数据域用于存放结点元素的值,节点元素的值为26个英文小写字母struct BitreeNode* lchild, * rchild;        //指针域,分别用于存放指向左右孩子的结点的指针}BitreeNode,*Bitree;//定义链栈结点
typedef struct LinkStackNode
{Bitree node;struct LinkStackNode* next;
}LinkStackNode,*LsNode;//定义链栈
typedef struct Linkstack
{LsNode top;                 //定义栈顶指针,栈顶是允许插入和删除的一端LsNode base;                //定义栈底指针,是不允许进行插入和删除元素的一端
}LinkStack,*Ls;//按照先序遍历结果创建一棵二叉树
void F_CreateBitree(Bitree root);
void MiddleOrderTraverse(Bitree root, Ls mystack);          //中序遍历//创建一个空栈
void InitStack(Ls mystack);//向栈中插入元素e
void InsertStack(Ls mystack, Bitree e);                 //向栈中插入元素不存在栈满问题但存在栈空问题,只能在栈顶处插入元素//若栈不空则删除栈顶元素,并将栈顶元素的值作为函数返回值返回
Bitree PopStack(Ls mystack);int main()
{LinkStack ls;Ls mystack = &ls;BitreeNode Bi;Bitree mytree = &Bi;//先序创建二叉树F_CreateBitree(mytree);//验证是否先序创建成功即先序遍历此二叉树看是否与我们再创建它时输入的节点序列是否一样;//创建一个空栈;InitStack(mystack);//printf("先序遍历结果:\n");//FirstOrderTraverse(mytree, mystack);printf("中序遍历结果:\n");MiddleOrderTraverse(mytree,mystack);//printf("后序遍历结果:\n");//PostOrderTraverse(mytree, mystack);return 0;}//使用递归算法,创建二叉树
void F_CreateBitree(Bitree root)
{//先序创建,遵循先创建根结点,再创建左子树最后在创建右子树,创建左右子树的时候递归调用此算法//输入根结点元素的值printf("请输入根结点的值\n");scanf("%c", &(root->data));getchar();//递归出口是输入#if (root->data == '#'){return;}//创建根结点元素的值//创建左子树,左子树递归调用本函数printf("请输入%c的左子树的根结点的值\n",root->data);root->lchild = (Bitree)malloc(sizeof(BitreeNode));F_CreateBitree(root->lchild);//创建右子树,右子树递归调用本函数printf("请输入%c的右子树的根节点的值\n",root->data);root->rchild = (Bitree)malloc(sizeof(BitreeNode));F_CreateBitree(root->rchild);if ((root->lchild)->data == '#'){root->lchild = NULL;}if ((root->rchild)->data == '#'){root->rchild = NULL;}}void InitStack(Ls mystack)
{mystack->top = mystack->base = (LsNode)malloc(sizeof(LinkStackNode));mystack->base->next = NULL;printf("创建空栈成功\n");
}void InsertStack(Ls mystack, Bitree e)
{LsNode p = (LsNode)malloc(sizeof(LinkStackNode));if (!p){printf("ERROR:申请内存失败\n");return;}p->node = e;p->next = mystack->top;mystack->top = p;
}Bitree PopStack(Ls mystack)
{if (mystack->top->next != NULL){LsNode temp;Bitree t;temp = mystack->top;t = temp->node;mystack->top = mystack->top->next;free(temp);return t;}return NULL;}void MiddleOrderTraverse(Bitree root,Ls mystack)
{//中序遍历,先遍历左子树,在遍历根结点,最后遍历右子树,对左右子树的遍历也遵循左根右的原则//利用栈来实现中序遍历的非递归算法Bitree m = root;//先判断二叉树是不是为空if (!root){return;}while (1){//根结点入栈Bitree temp;if (m){InsertStack(mystack, m);m = m->lchild;                        //先沿着左子树深入直到到达左子树为空的结点}else{temp = PopStack(mystack);               //当到达左子树为空的结点,将当前结点元素进行退栈,即输出当前结点的值,然后继续访问当前节点的右子树。//整个过程是不断重复地过程即沿着左子树深入直至为空,然会输出当前栈顶元素的值,然会返回上一结点元素,然后继续访问当前节点的右子树,所以有后深入的先返回的特性,//可以运用站的特性实现此算法,而实现返回上一个结点是通过退栈这一操作完成的printf("%c\t", temp->data);m = temp->rchild;}if ((mystack->top==mystack->base) && m == NULL){break;}}}

运行效果截图:

二叉树中序遍历的非递归算法相关推荐

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

    二叉树的后序遍历的非递归算法与二叉树的先序和中序遍历的非递归算法相比稍微复杂一点. 大致思路是:如果当前结点左右子树均为空,则可以访问当前结点,或者左右子树不均为空,但是前一个访问的结点是当前结点的左 ...

  2. 详细图解二叉树中序遍历(非递归C++)LeetCode94

    详细图解二叉树中序遍历(非递归) 二叉树中序递归含义 LeetCode题目94 详细图解 源代码 运行结果 二叉树中序递归含义 中序遍历首先遍历左子树,然后访问根结点,最后遍历右子树.若二叉树为空则结 ...

  3. 中序遍历的非递归算法

    void inordertraverse(bitree t) {initstack(s); p = t;q = new bitnode;while (p || !stackempty(s)){if ( ...

  4. 数据结构二叉树中序遍历递归和非递归算法

    2022.11.19 二叉树中序遍历递归和非递归算法 任务描述 相关知识 编程要求 测试说明 C/C++代码 任务描述 本关任务:给定一棵二叉树,使用递归和非递归的方法实现二叉树的中序遍历结果. 相关 ...

  5. 【C语言】二叉树中序遍历(递归和非递归)算法

    二叉树中序遍历的实现思想是: 访问当前节点的左子树: 访问根节点: 访问当前节点的右子树: 图 1 二叉树 以图  1 为例,采用中序遍历的思想遍历该二叉树的过程为: 访问该二叉树的根节点,找到 1: ...

  6. 二叉树中序遍历(递归+非递归)Java

    目录 一.结构 二.遍历二叉树 1.中序遍历(递归) 代码 图解 2.中序遍历(非递归) 代码 图解 一.结构 二.遍历二叉树 这块内容是二叉树最核心的部分.不但要掌握七种遍历的写法,前.中.后序的递 ...

  7. 二叉树——中序遍历(递归/非递归)

    中序遍历,即遍历顺序为:左节点.根节点.右节点. 二叉树节点: public class Node {public Node left;public Node right;public int val ...

  8. 二叉树中序遍历(递归法和迭代法(非递归法))——C++

    声明:本文原题主要来自力扣,记录此博客主要是为自己学习总结,不做任何商业等活动! 二叉树的遍历有前序遍历.中序遍历.后序遍历和层次遍历,其中二叉树基本知识点可以参考博主上篇博客(二叉树基本知识点图文介 ...

  9. Java 二叉树中序遍历(递归/非递归)

    Java 二叉树中序遍历(递归/非递归) 中序遍历 代码实现 递归方式 非递归方式 简介: 遍历是对树的一种最基本的运算,所谓遍历二叉树,就是按一定的规则和顺序走遍二叉树的所有结点,使每一个结点都被访 ...

最新文章

  1. flask_sqlalchemy 中 or 、 and 和 like 的用法
  2. Git 面对不同的场景的命令使用
  3. MySQL如何从开源中获利
  4. 如何做网络推广浅析在网站优化中如更换域名该如何避免降权风险?
  5. APL开发日志--2012-11-26
  6. Visual Studio 2012 C# ActiveX控件开发总结
  7. [css] 固定的外框尺寸,里面的图片尺寸不固定,如何让图像自适应外框呢?
  8. 专家答疑:在ERP系统中确保销售订单准确性
  9. linux中dpkg找不到命令_工作中常用的Linux命令介绍与实践
  10. ajax获取cpu的占用率,JavaScript获取当前cpu使用率的方法
  11. 小白的python之路Linux部分10/2829
  12. 果然有人向吾了解如果改进doubango的问题
  13. cocos2d-x 输入框CCEditBox的使用
  14. 学生晚上回宿舍时其在实验室的计算机主机,学生晚上回宿舍时,其在实验室的计算机主机应关闭,显示器一般不用关闭。...
  15. 6.13编一程序,将两个字符串连接起来,不要用strcat函数。
  16. 网络文件传输工具,秒杀各种网络文件传送工具的镭速云
  17. Android WIFI 分析
  18. Android Studio 主题 字体
  19. 杏子语录(2019年10月)
  20. 计算机的基础知识有哪些呢?

热门文章

  1. 云服务器大数据高可用集群搭建-----hadoop篇
  2. 极客大学产品经理训练营:产品经理的职业规划 第20课总结
  3. 电脑进入睡眠后,总是被唤醒
  4. Xplorasia(畅怀旅游)选择云呐资产管理为企业降本增效
  5. 本地文件上传FTP或远程目录
  6. 刮刮奖效果的简单实现
  7. windows无法连接到打印机?三个方法连接打印机(Win10系统)
  8. 微信小程序与内嵌网页交互实现支付功能
  9. JSAPI支付——H5网页端调起支付接口
  10. python下载某网站收费文档(一)——配合fiddler半自动版