实现二叉树的三种非递归遍历算法
【问题描述】
编写程序,实现二叉树的三种非递归遍历算法:先序非递归,中序非递归,后序非递归。
【输入形式】
输入建树序列。
【输出形式】
输出三种遍历序列。
【样例输入】
A
B
C
#
#
#
#
【样例输出】
ABC
CBA
CBA
要求:程序由接口文件(.h)和程序文件(.c)组成。接口文件包括:栈的结构、基本操作定义,二叉树的结构,二叉树的创建。程序文件包括三种非递归遍历定义及主函数。
我们需要在Code::Blocks中创建一个项目,里面的程序文件(.c)用来存放三种非递归遍历的定义及主函数。建立方式如下:
file->New->project->Console application
点击Next,(.c)文件创建完成。
接下来新建一个(.h)文件用来存放:栈的结构、基本操作定义,二叉树的结构,二叉树的创建。
File->New->Class->输入名称,点击creat->是->ok
输入名称,点击create
项目创建完成。
非递归算法中借助栈来完成整个遍历过程。步骤如下:
(1)当前指针指向根结点。
(2)若结点不为空,访问该结点。
(3)若结点右孩子不为空,则右孩子入栈。
(4)当前指针指向结点左孩子重复步骤(2)- 步骤(3),直到左孩子为空。
(5)依次退栈,当前指针指向出栈结点。
(6)若栈非空或当前指针非空,继续步骤(2),直到结束。
由此可写出先序遍历的非递归算法:
void PreOrder_n(BiTree p)
{BiTree stack[MAX],q;int top=0,i;for(i=0;i<MAX;i++)stack[i]=NULL;//初始化栈q=p;while(q!=NULL){printf("%c",q->data);//访问当前结点if(q->rchild!=NULL)stack[top++]=q->rchild;//当前结点右孩子进栈if(q->lchild!=NULL)q=q->lchild;//左子树不为空,进入左子树else if(top>0)q=stack[--top];//左子树为空,栈不空,则出栈else q=NULL;}
}
(.h)文件中栈的结构、基本操作定义,二叉树的结构,二叉树的创建。代码如下:
#include <stdio.h>
#include <stdlib.h>
#include <malloc.h>
#define MAX 20
#define ERROR 0
#define OK 1
#define STACK_INT_SIZE 10
#define STACKINCREMENT 5//二叉链表结点定义
typedef struct BTNode
{char data;struct BTNode *lchild;struct BTNode *rchild;
}*BiTree;void createBiTree(BiTree *t)
{
//此处补充代码,完成以先序遍历方式建立二叉树char s;BiTree q;s=getchar();getchar();if(s=='#'){*t=NULL;return;}q=(BiTree)malloc(sizeof(struct BTNode));q->data=s;*t=q;createBiTree(&q->lchild);createBiTree(&q->rchild);
}typedef BiTree ElemType;typedef struct
{ElemType *base;ElemType *top;int stacksize;
} SqStack;int initStack(SqStack *s);
int emptyStack(SqStack *s);
int pushStack(SqStack *s, ElemType e);
int popStack(SqStack *s,ElemType *e);
//初始化栈
int initStack(SqStack *s)
{s->base=(ElemType *)malloc(STACK_INT_SIZE*sizeof(ElemType));if(!s->base)return ERROR;s->top=s->base;s->stacksize=STACK_INT_SIZE;return OK;
}
//判断栈空
int emptyStack(SqStack *s)
{if(s->top==s->base)return OK;else return ERROR;
}
//入栈
int pushStack(SqStack *s, ElemType e)
{if(s->top-s->base>=s->stacksize){s->base=(ElemType *)realloc(s->base,(s->stacksize+STACKINCREMENT)*sizeof(ElemType));if(!s->base)return ERROR;s->top=s->base+s->stacksize;s->stacksize+=STACKINCREMENT;}*s->top++=e;return OK;
}
//出栈
int popStack(SqStack *s,ElemType *e)
{if(s->top==s->base)return ERROR;--s->top;*e=*s->top;return OK;
}
(.c)文件中三种递归遍历及主函数的代码如下:
#include "ec1.z.h"/*这里要用你自己创建的(.h)文件的名称*/void PreOrder_n(BiTree p)
{BiTree stack[MAX],q;int top=0,i;for(i=0;i<MAX;i++)stack[i]=NULL;//初始化栈q=p;while(q!=NULL){printf("%c",q->data);//访问当前结点if(q->rchild!=NULL)stack[top++]=q->rchild;//当前结点右孩子进栈if(q->lchild!=NULL)q=q->lchild;//左子树不为空,进入左子树else if(top>0)q=stack[--top];//左子树为空,栈不空,则出栈else q=NULL;}
}void InOrder_n(BiTree p)
{BiTree stack[MAX],q;int top=0,i;for(i=0;i<MAX;i++)stack[i]=NULL;//初始化栈q=p;while(q!=NULL||top>0){if(q!=NULL){stack[top++]=q;q=q->lchild;}else{q=stack[--top];printf("%c",q->data);q=q->rchild;}}
}void PostOrder_n(BiTree p)
{BiTree stack[MAX],q;int top=0,i,flag[MAX];for(i=0;i<MAX;i++)stack[i]=NULL;for(i=0;i<MAX;i++)flag[i]=0;q=p;i=0;while(q!=NULL||top>0){if(q){stack[top++]=q;flag[i++]=0;q=q->lchild;}else{while(top>0){if(flag[i-1]==0){q=stack[top-1]->rchild;flag[i-1]=1;break;}else{q=stack[--top];i--;printf("%c",q->data);}}}if(top==0)break;}
}int main()
{
//此处补充代码,按要求输出二叉树的叶子结点数和深度BiTree p;createBiTree(&p);PreOrder_n(p);printf("\n");InOrder_n(p);printf("\n");PostOrder_n(p);return 0;
}
运行结果如下:
实现二叉树的三种非递归遍历算法相关推荐
- 对于二叉树三种非递归遍历方式的理解
利用栈实现二叉树的先序,中序,后序遍历的非递归操作 栈是一种先进后出的数据结构,其本质应是记录作用,支撑回溯(即按原路线返回):因此,基于其的二叉树遍历操作深刻的体现了其特性: 若后续的输入和其前面的 ...
- 【树】二叉树的两种非递归遍历方法
非递归的遍历需要使用栈保存当前不输出的结点,并且三种遍历顺序步骤有所不同. 中序遍历 1.查看其当前结点是否为空: 若非空则将当前结点入栈,指针指向其左孩子: 若当前结点为空,说明上一个入栈的结点没有 ...
- 树:二叉树的非递归遍历算法
二叉树的递归遍历 二叉树的递归遍历算法,写法很简单,比如说前序遍历树,如下: //前序遍历 void PreOrderTraverse(BiTree tree) {if (NULL != tree){ ...
- 数据结构——二叉树的递归遍历算法与非递归遍历算法+层次遍历算法
(文章篇幅有点长,二叉树的递归遍历算法不作详细分析,但是二叉树的非递归遍历算法和层次遍历算法都有非常详细的分析过程,记得往下翻哦!) 二叉树的递归遍历算法实现 我们首先用递归的方法先序遍历创建这样一棵 ...
- 二叉树的后序非递归遍历(巧妙思想)
大家都知道二叉树的前序非递归遍历非常好写: //二叉树的结构 public class TreeNode {TreeNode left;TreeNode right;int val;TreeNode( ...
- 二叉树的中序非递归遍历
二叉树的中序非递归遍历 中序遍历的非递归算法描述如下: 从根节点开始检索,如果当前节点不为空,则将当前节点入栈,让当前节点成为其左孩子节点,再继续上一步的操作 加入当前节点为空了,说明其父节点已经没有 ...
- 树的递归与非递归遍历算法
树的递归与非递归遍历算法 树的递归与非递归遍历算法 树的遍历 实例 树遍历的口诀 树的递归遍历代码 树的先序遍历 树的中序遍历 树的后序遍历 递归遍历思想 树的非递归遍历 树的先序非递归遍历 先序遍历 ...
- 【数据结构笔记10】二叉树的先序、中序、后序遍历,中序遍历的堆栈/非递归遍历算法,层序遍历,确定一个二叉树,树的同构
本次笔记内容: 3.3.1 先序中序后序遍历 3.3.2 中序非递归遍历 3.3.3 层序遍历 3.3.4 遍历应用例子 小白专场:题意理解及二叉树表示 小白专场:程序框架.建树及同构判别 文章目录 ...
- 二叉树 中序非递归遍历算法 c++
二叉树的中序非递归算法,详见下 首先,二叉树结点定义 typedef struct BiTNode//二叉树结点结构 {string data;struct BiTNode *lchild,*rchi ...
最新文章
- 从支付宝看大用户规模互联网架构发展
- 为什么很多优秀的人,把闹钟定在早晨5:57?
- cpu缓冲区大小怎么设置_JAVA高薪面试必备知识点Volatile底层原理探究CPU在作怪
- 如何使用T-SQL生成随机SQL Server测试数据
- DataTable 中各种计算(笔记)
- 诺德尔-2011-2003-V1新版 ghost安装版
- [转]加载纹理与使用glGenTextures时应注意的一点(解决吃内存)
- SQLite:关于日期的字段的优化将给Julia带来大幅效率提升
- php实现新闻管理系统,PHP基础示范:用PHP+Mysql编写简易新闻管理系统_mysql
- IP,路由器工作原理、MAC,交换机工作原理、CSMA\CD、令牌环网
- Ncurses学习经历(九)屏幕操作
- 音频基础概念及常见编码格式
- 跳舞的小人 和 盲文
- 应用宝YSDK道具直接支付解决和遇到的坑
- Java中如何保证线程安全性
- 利用逆矩阵简化矩阵多项式
- seetaface6 android jni(二)
- f1c100s spi flash分区
- python seo编程_「SEO及应用编程」开课!
- 线性回归算法--拟合正弦函数