昨天写数据结构关于二叉树的几种顺序的递归及非递归遍历的程序,后续遍历有点难。现在把程序给大家参考一下,有些思路参考自:http://www.cnblogs.com/dolphin0520/archive/2011/08/25/2153720.html的思路。

一、先序遍历二叉树

1.递归遍历

每次先判断是否为空树,若不是则访问根节点,然后左子树,最后右子树。

void PreOrderTraverse1(BiTree T)
{//先序遍历二叉树T的递归算法
// cout<<"二叉树先序递归遍历\n";
if(T) //若二叉树非空
{
cout<<T->data; //访问根节点
PreOrderTraverse1(T->lchild); //遍历左孩子
PreOrderTraverse1(T->rchild); //遍历右孩子
}

}

2.非递归遍历

判断栈是否为空或子树为空,若不为空,就访问左孩子入栈,直至左孩子为空,若左孩子为空,就出栈,然后访问右孩子,入栈,就这样不断的循环。

void PreOrderTraverse2(BiTNode *T)
{//先序遍历二叉树T的非递归算法
// cout<<"二叉树先序非递归遍历\n";
StackNode *S;
BiTNode *p;
S=NULL;
S=InitStack(S);
p=T;

// cout<<"pre1.1\n";
if(p==NULL)
{
// cout<<"pre1.2\n";
cout<<"树为空\n";
return;
}
// cout<<"pre1.3\n";
while(p||!StackEmpty(S))
{

// cout<<"pre1.4\n";
if(p)
{
// cout<<"pre1.5\n";
Push(S,p);
cout<<p->data;
p=p->lchild;
}
else
{
// cout<<"pre1.6\n";
Pop(S,p);
p=p->rchild;
}
}
// cout<<"pre1.7\n";
}

二、中序遍历二叉树

1.递归遍历

每次先判断树是否为空,若不为空,则访问左子树,然后根子树,最后右子树。

void InOrderTraverse1(BiTree T)
{//中序遍历二叉树T的递归算法
// cout<<"二叉树中序递归遍历\n";
if(T) //若二叉树非空
{
InOrderTraverse1(T->lchild); //遍历左孩子
cout<<T->data; //访问根节点
InOrderTraverse1(T->rchild); //遍历右孩子
}

}

2.非递归遍历

思路基本和先序差不多,只是输出数据的时候不一样。判断栈和树是否为空,若不,则判断树是否为空,不为继续将左子树进栈,若为空,则出栈,输出数据,然后访问右子树。

void InOrderTraverse2(BiTree &T)
{//中序遍历二叉树T的非递归算法
// cout<<"二叉树中序非递归遍历\n";
StackNode *S;
BiTNode *p;
S=InitStack(S);
p=T;
while(p||!StackEmpty(S))
{
if(p)
{
Push(S,p);
p=p->lchild;
}
else
{
Pop(S,p);
cout<<p->data;
p=p->rchild;
}
}
}

三、后序遍历二叉树

1.递归遍历

先判断树是否为空,若不为,先左子树,后右子树,然后根节点。

void LastOrderTraverse1(BiTree T)
{//后序遍历二叉树T的递归算法
// cout<<"二叉树后序递归遍历\n";
if(T) //若二叉树非空
{
LastOrderTraverse1(T->lchild); //遍历左孩子
LastOrderTraverse1(T->rchild); //遍历右孩子
cout<<T->data; //访问根节点
}

}

2.非递归遍历

要保证根结点在左孩子和右孩子访问之后才能访问,因此对于任一结点P,先将其入栈。如果P不存在左孩子和右孩子,则可以直接访问它;或者P存在左孩子或者右孩子,但是其左孩子和右孩子都已被访问过了,则同样可以直接访问该结点。若非上述两种情况,则将P的右孩子和左孩子依次入栈,这样就保证了每次取栈顶元素的时候,左孩子在右孩子前面被访问,左孩子和右孩子都在根结点前面被访问。

void LastOrderTraverse2(BiTNode *T)
{//后序遍历二叉树T的非递归算法
// cout<<"二叉树后序非递归遍历\n";
StackNode *S;
BiTNode *p,*cur;
S=InitStack(S);
p=T;
p=NULL;cur=NULL;
Push(S,T);
while(!StackEmpty(S))
{
cur=NULL;
GetTop(S,cur);
if((cur->lchild==NULL && cur->rchild==NULL) || (p!=NULL &&(p==cur->lchild || p==cur->rchild)))
{
cout<<cur->data;
p=cur;
Pop(S,cur);

}
else
{
if(cur->rchild!=NULL)
{
Push(S,cur->rchild);
}
if(cur->lchild!=NULL)
{
Push(S,cur->lchild);
}
}
}
}

下面是完整的程序:

#include<stdio.h>
#include<stdlib.h>
#include<iostream>
using namespace std;

typedef struct BiTNode //树的结点
{
char data; //节点数据域
struct BiTNode *lchild,*rchild; //左右孩子指针
}BiTNode,*BiTree;

typedef BiTNode *SElemType;

typedef struct StackNode //栈的结点
{
SElemType data;
StackNode *next;
}StackNode;

StackNode *InitStack(StackNode *S)
{
S=(StackNode *)malloc(sizeof(StackNode));
if(S==NULL)
{
cout<<"内存不足,不能分配栈\n";
exit(0);
}
S->next=NULL;
return(S);
}

int StackEmpty(StackNode *S)
{
if(S->next==NULL)
{
return(1);
}
return(0);
}

void Push(StackNode *S,SElemType data)
{
StackNode *p;
p = (StackNode *)malloc(sizeof(StackNode));
if(p==NULL)
{
cout<<"内存不足,不能分配栈\n";
exit(0);
}
p->data=data;
p->next=S->next;
S->next=p;

}

void Pop(StackNode *S,SElemType &data)
{
StackNode *p;
if(S->next==NULL)
{
cout<<"栈为空,无返回值\n";
}
p=S->next;
data=p->data;
S->next=p->next;
free(p);

}

int GetTop(StackNode *S,SElemType &data)
{
if(S->next!=NULL)
{
data=S->next->data;
return(1);
}
else
{
return(0);
}
}

BiTNode *InitTree(BiTNode *T)
{
char data;
cin>>data;
if('#'==data)
{
T=NULL;
}
else
{
T=(BiTNode *)malloc(sizeof(BiTNode));
T->data=data;
T->lchild=InitTree(T->lchild);
T->rchild=InitTree(T->rchild);

}
return(T);
}

void PreOrderTraverse1(BiTree T)
{//先序遍历二叉树T的递归算法
// cout<<"二叉树先序递归遍历\n";
if(T) //若二叉树非空
{
cout<<T->data; //访问根节点
PreOrderTraverse1(T->lchild); //遍历左孩子
PreOrderTraverse1(T->rchild); //遍历右孩子
}

}

void InOrderTraverse1(BiTree T)
{//中序遍历二叉树T的递归算法
// cout<<"二叉树中序递归遍历\n";
if(T) //若二叉树非空
{
InOrderTraverse1(T->lchild); //遍历左孩子
cout<<T->data; //访问根节点
InOrderTraverse1(T->rchild); //遍历右孩子
}

}

void LastOrderTraverse1(BiTree T)
{//后序遍历二叉树T的递归算法
// cout<<"二叉树后序递归遍历\n";
if(T) //若二叉树非空
{
LastOrderTraverse1(T->lchild); //遍历左孩子
LastOrderTraverse1(T->rchild); //遍历右孩子
cout<<T->data; //访问根节点
}

}

void PreOrderTraverse2(BiTNode *T)
{//先序遍历二叉树T的非递归算法
// cout<<"二叉树先序非递归遍历\n";
StackNode *S;
BiTNode *p;
S=NULL;
S=InitStack(S);
p=T;

// cout<<"pre1.1\n";
if(p==NULL)
{
// cout<<"pre1.2\n";
cout<<"树为空\n";
return;
}
// cout<<"pre1.3\n";
while(p||!StackEmpty(S))
{

// cout<<"pre1.4\n";
if(p)
{
// cout<<"pre1.5\n";
Push(S,p);
cout<<p->data;
p=p->lchild;
}
else
{
// cout<<"pre1.6\n";
Pop(S,p);
p=p->rchild;
}
}
// cout<<"pre1.7\n";
}

void InOrderTraverse2(BiTree &T)
{//中序遍历二叉树T的非递归算法
// cout<<"二叉树中序非递归遍历\n";
StackNode *S;
BiTNode *p;
S=InitStack(S);
p=T;
while(p||!StackEmpty(S))
{
if(p)
{
Push(S,p);
p=p->lchild;
}
else
{
Pop(S,p);
cout<<p->data;
p=p->rchild;
}
}
}

void LastOrderTraverse2(BiTNode *T)
{//后序遍历二叉树T的非递归算法
// cout<<"二叉树后序非递归遍历\n";
StackNode *S;
BiTNode *p,*cur;
S=InitStack(S);
p=T;
p=NULL;cur=NULL;
Push(S,T);
while(!StackEmpty(S))
{
cur=NULL;
GetTop(S,cur);
if((cur->lchild==NULL && cur->rchild==NULL) || (p!=NULL &&(p==cur->lchild || p==cur->rchild)))
{
cout<<cur->data;
p=cur;
Pop(S,cur);

}
else
{
if(cur->rchild!=NULL)
{
Push(S,cur->rchild);
}
if(cur->lchild!=NULL)
{
Push(S,cur->lchild);
}
}
}
}

int main()
{
BiTNode *Tree;
Tree=NULL;
cout<<"按照层次遍历建立树,'#'表示树为空\n" <<endl;
cout<<"请输入要建立的树:"<<endl;
cout<<"\n";
Tree=InitTree(Tree);
int choose;
cout<<"请输入0(表示递归遍历)或1(表示非递归遍历)\n";
cin>>choose;
if(choose==0)
{
cout<<"二叉树先序递归遍历\n";
PreOrderTraverse1(Tree);
cout<<endl;
cout<<"二叉树中序递归遍历\n";
InOrderTraverse1(Tree);
cout<<endl;
cout<<"二叉树后序递归遍历\n";
LastOrderTraverse1(Tree);
cout<<endl;
}
else if(choose==1)
{
cout<<"二叉树先序非递归遍历\n";
PreOrderTraverse2(Tree);
cout<<endl;
cout<<"二叉树中序非递归遍历\n";
InOrderTraverse2(Tree);
cout<<endl;
cout<<"二叉树后序非递归遍历\n";
LastOrderTraverse2(Tree);
cout<<endl;
}
else
{
cout<<"输入错误\n"<<endl;
}
return 0;
}

转载于:https://www.cnblogs.com/xisheng/p/8094289.html

二叉树的先序,中序,后序,层次的递归及非递归遍历相关推荐

  1. 二叉树的前、中、后序遍历

    所谓二叉树遍历是按某种特定规则,依次对二叉树中的节点进行相应的操作,并且每个节点只操作一次.访问结点所做的操作依赖于具体的应用问题. 遍历是二叉树上最重要的运算之一,也是二叉树进行其它运算的基础. 二 ...

  2. 【数据结构与算法】力扣:二叉树的前、中、后序遍历

    递归法 前序遍历 给你二叉树的根节点 root ,返回它节点值的前序 遍历. 示例 1: 输入:root = [1,null,2,3] 输出:[1,2,3] 示例 2: 输入:root = [] 输出 ...

  3. 二叉树的前、中、后序遍历的代码实现(递归方式)

    测试的二叉树的结构 root lfb1 rtb1rtb2 控制台输出的遍历结果 ======从根节点开始,前序遍历此二叉树======= root lfb1 rtb1 rtb2 ======从根节点开 ...

  4. 二叉树的前、中、后、层次非递归遍历(js)

    有如下二叉树  遍历: // 前序遍历, head-left-rightfunction HLR (tree) {const stack = [], res = []if (tree) stack.p ...

  5. java中二叉树_Java工程师面试1000题224-递归非递归实现二叉树前、中、后序遍历...

    224.使用递归和非递归实现二叉树的前.中.后序遍历 使用递归来实现二叉树的前.中.后序遍历比较简单,直接给出代码,我们重点讨论非递归的实现. class Node { public int valu ...

  6. 二叉树遍历方法——前、中、后序遍历(图解)

    目录 一.前序遍历 (1)递归版本 (2)非递归版本 二.中序遍历 (1)递归版本 (2)非递归版本 三.后序遍历 (1)递归版本 (2)非递归版本 四.总结 五.测试程序 六.程序输出 二叉树的遍历 ...

  7. 二叉树的前、中、后的非递归遍历

    题目 实现一个链式存储的二叉树,采用非递归的形式,按照前.中.后序的顺序遍历二叉树. 代码 /** * 二叉树的前.中.后序的非递归遍历 **/#include <iostream> us ...

  8. 实验五 二叉树的递归及非递归的遍历及其应用

    实验目的 熟练掌握二叉树的二叉链表存储结构的C语言实现.掌握二叉树的基本操作-前序.中序.后序遍历二叉树的三种方法.了解非递归遍历过程中"栈"的作用和状态,而且能灵活运用遍历算法实 ...

  9. 已知一棵二叉树的中序序列和后序序列,写一个建立该二叉树的二叉链表存储结构的算法...

    已知一棵二叉树的中序序列和后序序列,写一个建立该二叉树的二叉链表存储结构的算法 #define N 10 //二叉树节点的个数 char postorderstr[]={};//后序序列 char i ...

  10. 分别用递归和非递归方式实现二叉树先序、中序和后序遍历(java实现)

    分别用递归和非递归方式实现二叉树先序.中序和后序遍历 用递归和非递归方式,分别按照二叉树先序.中序和后序打印所有的节点.我们约定:先序遍历顺序 为根.左.右;中序遍历顺序为左.根.右;后序遍历顺序为左 ...

最新文章

  1. 转: 视频相关的协议族介绍(rtsp, hls, rtmp)
  2. Sharepoint 2010 页面设计确实方便
  3. adaptiveThreshold函数
  4. 运行 命令 linux,Linux基本命令运行
  5. APP技巧:推荐6款超级实用的APP软件,赶快下载试试吧!
  6. mvc怎么请求服务器错误信息,asp.net-mvc – IIS显示服务器错误而不是自定义错误...
  7. 计算机视觉中的Transformer的最新进展!
  8. 对于国产芯片何时能挑大梁
  9. Windows API一日一练(60)CreateIoCompletionPort和GetQueuedCompletionStatus函数
  10. 最新sql 2008安装说明 以及 重设sql server 2008 R2的登录密码
  11. 2015年我走过的日子
  12. 【3D建模制作技巧分享】Zbrush如何将图片转浮雕模型
  13. chm文件打开文字排版错乱
  14. 缩写月份单词python_月份的英文单词、缩写及由来
  15. python爬虫构建国外代理池_Python爬虫入门(四)教你免费拥有自己的代理IP池
  16. Skype for Business Server 2015-07-边缘服务器-1-安装-先决条件
  17. iOS - 技术储备列表
  18. 【困扰了很久,实测已解决】MacBook上不了V2EX网站但Windows可以
  19. INPUT输入框带默认值
  20. NNDL 实验七 循环神经网络(3)LSTM的记忆能力实验

热门文章

  1. this cluster currently has [1946]/[1000] maximum shards open
  2. python 会计师事务所_Selenium爬取会计师事务所新闻信息——以中准会计师事务所为例...
  3. python3.7魔塔游戏_基于Funcode平台的“火锅版魔塔”游戏开发与设计
  4. vue和react对比
  5. uboot加载linux内核加载那些内容,uBoot和Linux内核中涉及到的几个地址参数的理解...
  6. vue 按钮根据状态切换_一个vue实现的标尺插件 - vue-sketch-ruler
  7. 20200327:最大矩形(leetcode85)
  8. 计算机图形学大几学的,计算机图形学大作业-WenhaoYu.PDF
  9. c语言基础符号,C语言符号大全。陆续更新基础知识给新人提供。(申精)
  10. java推送到 钉钉用户_javaweb利用钉钉机器人向钉钉群推送消息(解决中文乱码)...