链式二叉树的递归与遍历
//测试数据:EBH GAC F D
#include<iostream>
#include<cstdio>
#include<stack>
#include<queue>
using namespace std;
typedef char Elemtype;
//定义这棵树的结点
typedef struct node{Elemtype data;struct node *lchild;struct node *rchild;
}BitTree;
//递归先序遍历
void PreOrder(BitTree *bt)
{if(bt!=NULL){cout<<bt->data;PreOrder(bt->lchild);PreOrder(bt->rchild);}
}
//非递归先序遍历
void Preorder(BitTree *bt)
{BitTree *p;stack<BitTree *> s;s.push(bt);while(!s.empty()){p=s.top();s.pop();while(p){cout<<p->data;if(p->rchild) s.push(p->rchild);p=p->lchild;}}
}
//递归中序遍历
void InOrder(BitTree *bt)
{if(bt!=NULL){InOrder(bt->lchild);cout<<bt->data;InOrder(bt->rchild);}
}
//非递归中序遍历
void Inorder(BitTree *bt)
{stack<BitTree *> s;s.push(bt);BitTree *p;p=bt->lchild;while(p||!s.empty()){while(p){s.push(p);p=p->lchild;}p=s.top();s.pop();cout<<p->data;p=p->rchild;}
}
//递归后序遍历
void PostOrder(BitTree *bt)
{if(bt!=NULL){PostOrder(bt->lchild);PostOrder(bt->rchild);cout<<bt->data;}
}
//非递归后序遍历
void Postorder(BitTree *bt)
{stack<BitTree *> s;BitTree *p,*q;p=bt;q=NULL;while(p||!s.empty())//使用p的原因是方便第一次进入,优化代码{if(p!=q){while(p){s.push(p);if(p->lchild) p=p->lchild;else p=p->rchild;}}if(s.empty()) break;//写这句话的原因是访问根结点结束后,p为非空,所以还是能够进入循环,但堆栈已空,所以要用这句话推出q=s.top();if(q->rchild==p){s.pop();cout<<q->data;p=q;}else p=q->rchild;}
}
//二叉树的非递归层次遍历
void levelBitTree(BitTree *bt)
{queue<BitTree *> q;BitTree *p;p=NULL;p=bt;if(p) q.push(p);while(!q.empty()){p=q.front();q.pop();cout<<p->data;if(p->lchild) q.push(p->lchild);if(p->rchild) q.push(p->rchild);}
}
//建立二叉链表算法
BitTree *creBitTree()
{BitTree *bt; Elemtype x;scanf("%c",&x);if(x==' ') bt=NULL;else{bt=(BitTree *)malloc(sizeof(BitTree));bt->data=x;bt->lchild=creBitTree();bt->rchild=creBitTree();}return bt;
}
//统计二叉树中叶子节点的个数
int cleaf=0;
void countleaf(BitTree *bt)
{if(bt!=NULL){if(bt->lchild==NULL&&bt->rchild==NULL) cleaf++;countleaf(bt->lchild);countleaf(bt->rchild);}
}
//交换二叉树中所有结点的左右子树
void exchange(BitTree *bt)
{BitTree *t;if(bt!=NULL){if(bt->lchild!=NULL||bt->rchild!=NULL){t=bt->lchild;bt->lchild=bt->rchild;bt->rchild=t;}exchange(bt->lchild);exchange(bt->rchild);}
}
//求二叉树的高度
int hightree(BitTree *bt)
{int h,h1,h2;if(bt==NULL) h=0;else{h1=hightree(bt->lchild);h2=hightree(bt->rchild);h=(h1>h2?h1:h2)+1;}return h;
}
//查找值为x的结点
int ok=0;
void searchtree(BitTree *bt,Elemtype x,BitTree **p1)
{if(bt!=NULL&&!ok){if(bt->data==x){ok=1;*p1=bt;}else{*p1=NULL;searchtree(bt->lchild,x,p1);searchtree(bt->rchild,x,p1);}}
}
//删除值为x的结点,使得其左右子树的安排仍然满足原来的中序遍历序列
/*分析:为了保持中序遍历序列不变,对于找到的结点p可以分为4种情况考虑(1)若结点p为叶子结点,则只需将该结点p的双亲结点f的左指针或右指针置为空即可(2)若结点p的左子树为空,则只需将该结点p的双亲结点f的左指针或右指针指向该结点p的右孩子即可(3)若结点p的左子树非空,则只需找到结点p的左子树中最右下的结点s(s的右指针必为空),将该结点s的左子树接到该结点s的双亲结点q上,再用该结点s中的数据替换p中的数据,最后删除该结点(s)即可(4)若结点p为根结点bt且该结点左子树为空,则只需将根结点的指针bt移到结点p的右子树上即可详细图解分析在 秦玉平 马靖善所编的数据结构(第三版) p129-129的例5.14*/
//为了此功能专门设计的查找函数,f记录双亲结点,p记录查找到的结点
int Find=0;
void search(BitTree *bt,Elemtype x,BitTree **p,BitTree **f)
{if(bt!=NULL&&!Find){if(bt->data==x){Find=1;*p=bt;}else{if(!Find){*f=bt;search(bt->lchild,x,p,f);}if(!Find){*f=bt;search(bt->rchild,x,p,f);}}}
}
//删除x的函数
void deltree(BitTree **bt,Elemtype x)
{BitTree *p,*f;BitTree *q,*s;p=f=NULL;search(*bt,x,&p,&f);if(p!=NULL){if(p->lchild!=NULL){q=p->lchild;s=q;while(s->rchild!=NULL){q=s;s=s->rchild;}if(q!=s) q->rchild=s->lchild;else p->lchild=q->lchild;p->data=s->data;free(s);}else{if(f!=NULL){if(p==f->lchild) f->lchild=p->rchild;else f->rchild=p->rchild;}else*bt=(*bt)->rchild;free(p);}}elsecout<<"Not find this node"<<endl;
}
int main()
{BitTree *bt;
// BitTree **p1;
// Elemtype x;
// Elemtype y;
// int h;bt=creBitTree();//建树
// PreOrder(bt);//递归先序
// cout<<endl;
// InOrder(bt);//递归中序
// cout<<endl;
// PostOrder(bt);//递归后序
// cout<<endl;
// countleaf(bt);//统计叶子结点个数
// cout<<cleaf<<endl;
// exchange(bt);
// PreOrder(bt);//递归先序
// cout<<endl;
// InOrder(bt);//递归中序
// cout<<endl;
// PostOrder(bt);//递归后序
// cout<<endl;
// h=hightree(bt);//求树的高度
// cout<<h<<endl;
// cin>>x;
// p1=(BitTree **)malloc(sizeof(BitTree));//给**p开辟空间
// searchtree(bt,x,p1);//找到x,并把x的地址存放在p里面,注意,p放的是x的地址,而不是这个地址里的内容
// cout<<(*p1)->data<<endl;//输出p指的内容,也就是找到的x
// cin>>y;
// deltree(&bt,y);
// InOrder(bt);//递归中序
// cout<<endl;
// Preorder(bt);//非递归先序遍历
// cout<<endl;
// Inorder(bt);//非递归中序遍历
// cout<<endl;
// Postorder(bt);//非递归后序遍历
// cout<<endl;levelBitTree(bt);cout<<endl;return 0;
}
链式二叉树的递归与遍历相关推荐
- 链式二叉树的创建、遍历和遍历算法的应用
目录
- 【C】二叉树--顺序结构(详解堆的实现,topK排序、堆排)、和链式结构(链式结构的遍历、链式结构常见递归操作以及练习题)
本章我们将引入树的概念并详细介绍二叉树.我们会在介绍顺序二叉树基础上,进一步介绍堆以及堆的实现,并以此为依据详解topK排序.堆排等问题:然后我们会介绍链式二叉树的实现以及各种操作.最后,我们也会给出 ...
- 链式二叉树的代码实现
目录 二叉树的存储结构: 链式二叉树的实现 1.二叉树的结构体类型 2.创建二叉树结点 代码实现: 3.二叉树的前序遍历 测试结果: 4.二叉树的中序遍历 测试结果: 5.二叉树的后序遍历 测试结果: ...
- 后序遍历链式二叉树(递归和非递归)
#include<stdio.h> #include<stdlib.h> #define MAXSIZE 100//二叉树的结点 typedef struct Node {ch ...
- 二叉树(二)----->链式二叉树(上)
文章的主体内容 1.链式二叉树链式二叉树的表示法 2.二叉树的前中后序遍历思想 3.求二叉树节点的个数及叶子节点的个数及第k层节点数 5.查找二叉树值为x的节点 6.二叉树的层序遍历 7.二叉树的深度 ...
- 顺序二叉树(堆)与链式二叉树的C语言实现
文章目录 树的概念及结构 树的概念 树的相关概念 树的表示 树在实际中的运用 二叉树的概念及结构 二叉树的概念 现实中的二叉树 特殊的二叉树 二叉树的性质 二叉树的存储结构 二叉树的顺序结构及实现 二 ...
- 数据结构树状结构链式二叉树
链式二叉树: 遍历: 前序 中序 后序 下面是具体实现: 1.前序遍历: void PreTraverseLTree(struct LTNode *pT) {if(pT!=NULL){cout< ...
- 二叉树(递归)遍历流程图怎么画?
只要理解了递归算法的实质,以及二叉树三种遍历的访问顺序,它们的流程图就不难画出来(文章附上了二叉树三种遍历的流程图画法).接下来,将从三部分进行深度解读: 什么是递归? 二叉树的三种遍历 如何将三种遍 ...
- php之二叉树,PHP数据结构之实现链式二叉树与遍历
/******************************************************** * 我写的PHP都是从C语言的数据结构中演化而来****************** ...
- 数据结构初阶——链式二叉树
目录 树概念及结构 树的概念 树的表示 二叉树概念及结构 概念 特殊二叉树 二叉树的性质 二叉树链式结构及实现 二叉树的简单创建 二叉树的前序遍历 二叉树中序遍历与二叉树后序遍历 求二叉树节点个数 求 ...
最新文章
- Reporting service个人使用经验
- UA OPTI570 量子力学3 单个自由粒子的薛定谔方程
- PHP中文乱码的常见解决方法总结
- Java删除文件和目录
- FreeRTOS--API函数
- 特定领域因果事件图谱构建项目
- 创建用户的种类与区分
- css3获取当前时间并显示,实时获取当前时间并展示在页面上
- 搜索推荐广告中的Position Bias:美团DPIN
- 入党对程序员有什么用_为什么程序员都喜欢用两个大屏显示器?网友:一个复制一个粘贴...
- 二分法查找是基于有序_【二分查找】May1th “First Bad Version (Python3)”
- 用DELPHI为ASP开发文件上载组件
- 面向电缆行业的高级计划与排程(商简SPS)解决方案
- kafka安装包下载慢,国内镜像下载地址
- 知乎提示浏览器版本过低的完美解决办法
- java中文转繁体汉字
- 设计师:设计师知识储备之硬装部分/软装部分简介、家装材料知识(吊顶材料/门窗材料/五金材料/墙面材料/地面材料/胶粘材料/油漆材料/水电材料/瓦工部分)之详细攻略
- Oracle数据库PL/SQL块-存储函数和过程
- ccproxy受瑞星杀毒软件影响
- ueditor(JSP版)如何实现word文档的导入和下载功能