要求:以左右孩子表示法实现链式方式存储的二叉树(lson—rson),以菜单方式设计并完成功能任务:建立并存储树、输出前序遍历结果、输出中序遍历结果、输出后序遍历结果、交换左右子树、统计高度,其中对于中序、后序的遍历运算要求采用非递归的方式实现。

写在前面

二叉树向量存储的优势和弊端

  二叉树同样有两种存储方式,数组和链式存储,对于数组来说,我们利用二叉树的性质然后利用下标可以方便的找到一个节点的子节点和父节点。

    

  

二叉树的性质:
  1.二叉树的第i层上至多有2i-1个节点
  2.深度为K的二叉树至多有2k-1个节点
  3.任何一个二叉树中度数为2的节点的个数必度数为0的节点数目少1.
    说明:度数为0,为叶子节点。
  4.具有n个节点的完全二叉树的深度为|_Log2N_|+1
  5.若完全二叉树中的某节点编号为i,则若有左孩子编号为2i,若有右孩子编号为2i+1,母亲节点为i/2。

  结合第5条性质:

    若完全二叉树中的某节点编号为i,则若有左孩子编号为2i,若有右孩子编号为2i+1,母亲节点为i/2。

  可以在这种完全二叉树中十分方便的找到任何相关联(父子、兄弟等)的元素。

  但是由于顺序存储天生适配于完全二叉树,对于下面这种非完全二叉树并不合适,主要体现在空间上的浪费,所以我们需要用到另一种存储方式——链式存储。

   

 

二叉树的链表存储

  在链式存储中,每个节点的结构如下

  

结构描述:

  一个存储数据的变量与两个指向孩子的指针域。

  利用指针域我们便可以完美的存储非完全二叉树,如下:

   

代码分解:

1.定义结构体变量,其中的tag只会在后序遍历(非递归)过程中使用。

typedef struct node{
int tag; //在后序遍历过程中来标志一个结点是第一次访问(tag=0)还是第二次访问(tag=1)
int data;
struct node* lson;
struct node* rson;
}Bitree;
typedef Bitree* Bitpo;

2.创建二叉树。创建二叉树的方式有3种(前序、中序、后序),其过程与二叉树的遍历类似,这里我用前序来创建二叉树。

void create(Bitpo &T){                    //创建并存储二叉树,以先序顺序输入并存储(递归)
int x;
cin>>x;
if(x==0) //'0'表示空节点
T=NULL;
else{
T=(Bitpo)malloc(Len);
T->data=x;
create(T->lson);
create(T->rson);
}
}

3.前序遍历二叉树(递归)。

void pretraversal(Bitpo T){              //先序遍历(递归)
if(T){
cout<<T->data<<" ";
pretraversal(T->lson);
pretraversal(T->rson);
}
}

4.中序遍历二叉树(非递归)。这里用数组模拟栈,用一个整型变量模拟栈顶指针,需要回溯。

void intraversal(Bitpo T){               //中序遍历(非递归)
Bitpo stack[101]; //定义栈并初始化
Bitpo Q=T;
int p=0; //初始化栈顶指针
do{
while(Q!=NULL){ //遍历左子树
p++;
if(p==101){
cout<<"Error:stack is full!!";
return; //栈满,返回0
}
stack[p]=Q; //入栈,从下标1开始
Q=Q->lson;
}
if(p!=0){
Q=stack[p];
p--; //退栈
cout<<Q->data<<" "; //访问根节点
Q=Q->rson; //遍历右子树
}
}while(p!=0||Q!=NULL);
}

5.后序遍历二叉树(非递归)。同样的用数组模拟栈,用一个整型变量模拟栈顶指针,需要回溯和设立标志tag(已在结构体中定义),因为根节点最后一个访问,所以入栈时令tag=0入栈,第一次回溯出栈时令tag=1,重新入栈,第二次回溯出栈时才可以访问。

void posttraversal(Bitpo T){             //后序遍历(非递归)
Bitpo stack[101]; //定义栈并初始化
int p=0; //初始化栈顶指针
Bitpo Q=T;
do{
while(Q!=NULL){
p++;
if(p==101){ //栈满,退出
cout<<"Error:stack is full!!";
return;
}
Q->tag=0; //第一次入栈,tag=0
stack[p]=Q; //入栈
Q=Q->lson;
}
if(p!=0){
Q=stack[p];
p--; //退栈
if(Q->tag==0){ //第一次访问,令tag=1,重新入栈
Q->tag=1;
p++;
stack[p]=Q;
Q=Q->rson;//继续搜索Q的右子树
}
else{ //第二次入栈,访问Q结点,并且为了回溯,令Q=NULL
cout<<Q->data<<" ";
Q=NULL;
}
}
}while(p!=0||Q!=NULL);
}

6.交换左右子树(递归)。

void exchange(Bitpo T){                  //交换左右子树(递归)
if(T){
Bitpo x=T->lson;
T->lson=T->rson;
T->rson=x;
exchange(T->lson);
exchange(T->rson);
}
}

7.求二叉树的高度(递归)。

int height(Bitpo T){                     //求高度(递归)
if(T){
return 1+max(height(T->lson),height(T->rson));
}
else
return 0;
}

8.主函数如下。

int main(){
int q=1;
Bitpo root;
while(q){
cout<<"1.create and store binary tree!"<<endl;
cout<<"2.travel in preorder!"<<endl;
cout<<"3.travel in inorder!"<<endl;
cout<<"4.travel in postorder!"<<endl;
cout<<"5.change lson and rson!"<<endl;
cout<<"6.calculate the height of the tree!"<<endl;
cout<<"0.exit!"<<endl;
cin>>q;
switch(q){
case 0:
q=0;
break;
case 1:
create(root);
cout<<endl<<"create successfully!"<<endl<<endl;
break;
case 2:
cout<<"preorder:";
pretraversal(root);
cout<<endl<<endl;
break;
case 3:
cout<<"inorder:";
intraversal(root);
cout<<endl<<endl;
break;
case 4:
cout<<"postorder:";
posttraversal(root);
cout<<endl<<endl;
break;
case 5:
exchange(root);
cout<<"exchange successfully!!"<<endl<<endl;
break;
case 6:
cout<<"height:"<<height(root)<<endl<<endl;
break;
}
}
return 0;
}

二叉树的创建、遍历(递归和非递归实现)、交换左右子数、求高度(c++实现)的更多相关文章

  1. 数据结构二叉树的递归与非递归遍历之java,javascript,php实现可编译(1)java

    前一段时间,学习数据结构的各种算法,概念不难理解,只是被C++的指针给弄的犯糊涂,于是用java,web,javascript,分别去实现数据结构的各种算法. 二叉树的遍历,本分享只是以二叉树中的先序 ...

  2. C实现二叉树(模块化集成,遍历的递归与非递归实现)

    C实现二叉树模块化集成 实验源码介绍(源代码的总体介绍):header.h : 头文件链栈,循环队列,二叉树的结构声明和相关函数的声明.LinkStack.c : 链栈的相关操作函数定义.Queue. ...

  3. 二叉树3种递归和非递归遍历(Java)

    import java.util.Stack; //二叉树3种递归和非递归遍历(Java) public class Traverse { /******************一二进制树的定义*** ...

  4. JAVA递归、非递归遍历二叉树(转)

    原文链接: JAVA递归.非递归遍历二叉树 import java.util.Stack; import java.util.HashMap; public class BinTree { priva ...

  5. 二叉树前中后/层次遍历的递归与非递归形式(c++)

    /* 二叉树前中后/层次遍历的递归与非递归形式 */ //*************** void preOrder1(BinaryTreeNode* pRoot) { if(pRoot==NULL) ...

  6. Java实现二叉树的先序、中序、后序、层序遍历(递归和非递归)

    二叉树是一种非常重要的数据结构,很多其它数据结构都是基于二叉树的基础演变而来的.对于二叉树,有前序.中序以及后序三种遍历方法.因为树的定义本身就是递归定义,因此采用递归的方法去实现树的三种遍历不仅容易 ...

  7. Java - 二叉树递归与非递归

    树的定义具有递归特性,因此用递归来遍历比较符合特性,但是用非递归方式就比较麻烦,主要是递归和栈的转换. import java.util.Stack; /** * @author 李文浩 * @ver ...

  8. 数据结构-树以及深度、广度优先遍历(递归和非递归,python实现)

    前面我们介绍了队列.堆栈.链表,你亲自动手实践了吗?今天我们来到了树的部分,树在数据结构中是非常重要的一部分,树的应用有很多很多,树的种类也有很多很多,今天我们就先来创建一个普通的树.其他各种各样的树 ...

  9. 数据结构作业——图的存储及遍历(邻接矩阵、邻接表+DFS递归、非递归+BFS)

    邻接矩阵存图 /* * @Author: WZY * @School: HPU * @Date: 2018-11-02 18:35:27 * @Last Modified by: WZY * @Las ...

  10. 二叉树之AVL树的平衡实现(递归与非递归)

    这篇文章用来复习AVL的平衡操作,分别会介绍其旋转操作的递归与非递归实现,但是最终带有插入示例的版本会以递归呈现. 下面这张图绘制了需要旋转操作的8种情况.(我要给做这张图的兄弟一个赞)后面会给出这八 ...

随机推荐

  1. Spring Cloud构建微服务架构(七)消息总线

    先回顾一下,在之前的Spring Cloud Config的介绍中,我们还留了一个悬念:如何实现对配置信息的实时更新.虽然,我们已经能够通过/refresh接口和Git仓库的Web Hook来实现Gi ...

  2. sed简单用法

    参数说明: -e 以指定的script来处理输入的文本文件 -f 以指定的script文件来处理输入的文本文件 -h 显示帮助 -n 仅显示script处理后的结果 -V 显示版本信息 -v 反选 动 ...

  3. 每秒查询率QPS

    每秒查询率QPS是对一个特定的查询服务器在规定时间内所处理流量多少的衡量标准,在因特网上,作为域名系统服务器的机器的性能经常用每秒查询率来衡量. 原理:每天80%的访问集中在20%的时间里,这20%时 ...

  4. 外网访问XAMPP失败 解决方案

    xampp 访问出现New XAMPP security concept 收藏 New XAMPP security concept: Access to the requested director ...

  5. 文件的编辑命令-echo/cat

    touch test.yaml echo "line1 line2" >> test.yaml cat test.yaml line1 line2 # 创建test.y ...

  6. leetcode167

    public class Solution { public int[] TwoSum(int[] numbers, int target) { Dictionary<int, int> ...

  7. Delphi Berlin 窗体代码分离风格 回到Delphi7传统风格

    回到Delphi7传统风格 Floating Form Designer You can now detach the form designer in both, VCL and FireMonke ...

  8. egret 配置设置

    修改index.html的时候,要主要template文件夹下的web文件夹也有个index.html,两者控制的不一样 初始安装新建项目后调试这样的情况.重新安装引擎和下载egret安装包安装,默认 ...

  9. as3 文档类判断是否被加载

    if (!stage) { trace(("被加载->this.parent:" + this.parent)); }else { trace(("单独打开-> ...

  10. as3 string split方法一些注意

    split () 方法 AS3 function split(delimiter:*, limit:Number = 0x7fffffff):Array 如果指定 limit 参数,返回的数组中具有的 ...