数据结构(二叉树子系统:c语言实现)
来源:互联网 发布:微信第三方平台 php 编辑:程序博客网 时间:2024/04/30 15:22
#include<stdio.h>#include<stdlib.h>#define datatype char#define M 50#define MAXLEN 50int num=0,counter1=0,counter2=0;typedef struct node //定义一个二叉链表结构{datatype data;int lt,rt;struct node *lchild,*rchild;}BT;BT* createtree() // 1---创 建 树{BT *bt;datatype x;scanf("\n%c",&x);if(x=='0') //指针为空的标志{bt=NULL; //}else{bt=(BT*)malloc(sizeof(BT)); // 申请一个新的的结点空间bt->data=x;bt->lchild=createtree(); // 创建结点的左子树bt->rchild=createtree(); // 创建结点的右子树 } return bt;}ShowTree(BT *T) //2--- 显 示 树{int i;if(T==NULL){ return; //当结点为空, } else { num++; //全局变量 num 调控结点的位置printf("\t\t\t"); for(i=0;i<num;i++) { printf(" ");} printf("%c",T->data); for(i=0;i<20-num*2;i++) {printf("-");}printf("\n"); ShowTree(T->lchild); // 显示结点的左子树 ShowTree(T->rchild); // 显示结点的右子树 num=num-1; }}void Preorder(BT *T) // 3---先 序 遍 历 树{ if(T==NULL) { return; } else // 本函数调用结束 { printf("%c ",T->data); // 输出结点的数据域 Preorder(T->lchild); // 先序递归遍历左子树 Preorder(T->rchild); // 先序递归遍历右子树 }}void Inorder(BT *T) // 4---中 序 遍 历 树{if(T==NULL) { return; } else // 本函数调用结束 { Inorder(T->lchild); // 中序递归遍历左子树 printf("%c ",T->data); // 输出结点的数据域 Inorder(T->rchild); // 中序递归遍历右子树 }}void Postorder(BT *T) // 5---后 序 遍 历 树{if(T==NULL) { return; // 本函数调用结束 } else { Postorder(T->lchild); // 后序递归遍历左子树 Postorder(T->rchild); // 后序递归遍历右子树 printf("%c ",T->data); // 输出结点的数据域 }}/* 算法思想 引用BT指针类型的数组(类似栈结构)来保存每个结点和它的左指针; 由于知道它的结点就可以知道它的左子树,所以只需要保存它的结点; 非空树 循环 1.结点指针入栈,直到结点左子树为空;2.结点出栈,输出出栈结点的值,访问结点右子树;3.栈和结点右子树不为空继续循环;*/void inorderse(BT *bt) //6---中序非递归遍历树{int i=0; //栈的初始化 BT *p,*s[M]; //保存每个结点的指针的栈 p=bt; do {while(p!=NULL) {s[i++]=p; //结点的指针入栈 p=p->lchild; //进入左子树 } //左子树为空,退出 if(i>0) //如果栈不空{ p=s[--i]; //结点的指针出栈 printf("%c ",p->data); //访问出栈的结点 p=p->rchild; } }while(i>0||p!=NULL); //右子树为空同时栈空,结束循环}/* 算法思想 从二叉树根结点开始,先将根结点指针放入队中,然后从队头取出一个结点元素,每取出一个元素,执行以下操作1.输出该结点元素的值。2.若该结点左,右子树不为空,分别把该结点的左,右子树结点入队。*/void Levelorder(BT *T) // 7----按层次遍历二叉树BT, T 为指向根结点的指针{int i,j; BT *q[MAXLEN],*p; // q为指针数组用以模拟队列,每个元素均为指向BT类型的指针, 用来存放结点地址 p=T; if (p!=NULL) // 若二叉树非空,则根结点地址入队 {i=1;q[i]=p;j=2; } // i 指向对头,j 指向对尾 while (i!=j) // 当队列不为空时执行循环 {p=q[i];printf("%c ",p->data); // 访问队首结点的数据域 if( p->lchild!=NULL) {q[j]=p->lchild; j++;} // 将出队结点的左孩子的地址入队 if(p->rchild!=NULL) {q[j]=p->rchild;j++;} // 将出队结点的右孩子的地址入队 i++; }}BT *zxxsh(BT *T) //8----中序非递归线索化二叉树{BT *p,*pr,*s[M],*t; // int i=0; // 计数变量 t=(BT*)malloc(sizeof(BT)); t->lt=0; // lt 域为指针域 t->rt=1; // rt 域为线索域 t->rchild=t; // 线索后继(右)指向结点本身 if(T==NULL){t->lchild=t; // 左子树指向结点本身}else {t->lchild=T; // 左子树指向 bt指针 指向的结点pr=t;p=T; //do{while(p!=NULL){s[i++]=p; // 结点指针入栈p=p->lchild; // 进入左子树}if(i>0){p=s[--i]; // 结点指针出栈printf("%c ",p->data);if(p->lchild==NULL){p->lt=1; // lt 域为线索域p->lchild=pr; // 线索前驱指向 pr指针}if(pr->rchild==NULL){pr->rt=1; // rt 域为线索域pr->rchild=p; // 线索前驱指针指向 p指针}pr=p;p=p->rchild; }}while(i>0||p!=NULL);pr->rchild=t;pr->rt=1;t->rchild=pr; }return t;}void zxblxss (BT *t) // 9----中序遍历找后继线索化二叉树{BT *p; p=t->lchild;do{while(p->lt==0){p=p->lchild; // 最左的结点} printf("%c ",p->data); // 输出最左结点或右子树的左链尾 while( (p->rt==1)&&(p->rchild!=t) ) // 为线索且不是中序的尾结点 {p=p->rchild; // p指向直接后继。 printf("%c ",p->data); // 输出直接后继结点 } p=p->rchild; // p指向右子树 } while( p!=t ); }/* 算法思想 从二叉树T的根结点开始,若二叉树的根结点的左,右子树都为空,该结点为叶子节点; 递归统计树T的左子树结点。 递归统计树T的右子树结点。*/void Nodenum(BT *T) //10-----统计数总结点数{if(T==NULL){return;}else{counter2++; // 全局变量counter2,Nodenum(T->lchild); // 递归统计结点左子树结点个数Nodenum(T->rchild); // 递归统计结点右子树结点个数}}/* 算法思想 从根结点开始,若结点左,右子树都为空,该结点为树的叶子结点,counter1++ 递归统计左子树上的叶子节点; 递归统计右子树上的叶子节点;*/void Leafnum(BT *T) // 11-----叶 子 节 点 数{if(T==NULL) // 开始时,T为根结点所在链结点的指针。{return; // 若树为空,什么也不做,返回主调函数。}else{if(T->lchild==NULL&&T->rchild==NULL){counter1++; // 统计叶子结点个数的全局变量 count(初值为0)加1。}Leafnum(T->lchild); // 递归统计 T 的左子树叶子结点数。Leafnum(T->rchild); // 递归统计 T 的右子树叶子结点数}}/* 算法思想 从根结点开始,结点为空,返回树层数为零。 否则递归统计左,右子树的层次数; 返回左右子树中层次数较大的那一个; */int TreeDepth(BT *T) // 12----树 深 度{int ldep,rdep; // 定义两个变量,存放左、右子树的深度if(T==NULL){return 0;}else{ldep=TreeDepth(T->lchild); // 递归统计左子树深度rdep=TreeDepth(T->rchild); // 递归统计右子树深度if(ldep>rdep){return ldep+1;}else{return rdep+1;}}}/* 算法思想 从根结点开始,在树T中查找与x相等的值,若存在则返回该结点的地址, 先从根结点开始,根结点不满足条件,则在结点的左,右子树中查找x的值;*/int mask=0;void Search(BT *T,datatype x){if(T==NULL){return ;}else{if(T->data==x){mask=1;}Search(T->lchild,x);Search(T->rchild,x);}}void meau(){printf("\n\t\t\t 二 叉 树 子 系 统 \n");printf("\t**************************************************************\n");printf("\t* 1------建立二叉树的二叉链表存储结构 *\n");printf("\t* 2------按凹入表显示二叉树 *\n");printf("\t* 3------按先序遍历二叉树 *\n");printf("\t* 4------按中序遍历二叉树 *\n");printf("\t* 5------按后序遍历二叉树 *\n");printf("\t* 6------按中序非递归调用算法遍历二叉树 *\n");printf("\t* 7------按层次遍历二叉树 *\n");printf("\t* 8------按中序非递归调用线索化二叉树 *\n");printf("\t* 9------按找后继(或前驱)结点的算法遍历中序线索二叉树 *\n");printf("\t* 10-----统计二叉树的结点总数 *\n");printf("\t* 11-----统计二叉树的叶子结点总数 *\n");printf("\t* 12-----统计二叉树的深度 *\n");printf("\t* 13-----在二叉树中查找值为x的结点 *\n");printf("\t* 0------返 回 *\n");printf("\t**************************************************************\n");printf("\t 请选择要执行的操作代号(0--13): ");}void main(){int i,chiose;datatype x;BT *T,*t;while(1){meau();scanf("%d",&chiose);if(chiose==1){printf("\n\t 按先序次序输入二叉树中结点的值,以0字符表示空树\n");printf("\t请输入: ");T=createtree();printf("\t 数据输入完毕!\n");}else if(chiose==2){printf("\n\t\t\t凹入表显示二叉树\n");ShowTree(T);}else if(chiose==3){printf("\n\t\t先序遍历二叉树: ");Preorder(T);printf("\n");}else if(chiose==4){printf("\n\t\t中序遍历二叉树: ");Inorder(T);printf("\n");}else if(chiose==5){printf("\n\t\t后序遍历二叉树: ");Postorder(T);printf("\n");}else if(chiose==6){printf("\n\t\t中序非递归遍历二叉树: ");inorderse(T);printf("\n");}else if(chiose==7){printf("\n\t\t层次遍历二叉树: ");Levelorder(T);printf("\n");}else if(chiose==8){printf("\n\t\t中序非递归线索化二叉树为: ");t=zxxsh(T);printf("\n");}else if(chiose==9){printf("\n\t\t中序遍历找后继线索化二叉树:");zxblxss(t);printf("\n");}else if(chiose==10){Nodenum(T);printf("\n\t树的节点数为: %d\n",counter2);counter2=0;}else if(chiose==11){Leafnum(T);printf("\n\t树的叶子节点数为: %d\n",counter1);counter1=0;}else if(chiose==12){printf("\n\t树的深度为: %d\n",TreeDepth(T));}else if(chiose==13){printf("\n\t 输入你要查询的数据:");scanf("\n%c",&x);Search(T,x);if(mask==1){printf("\n\t 你要查找的数据%c在二叉树中\n",x);}else{printf("\n\t 你要查找的数据%c不在二叉树中\n",x);}mask=0;}else if(chiose==0){break;}else{printf("\n\t\t 输入有误,请重新选择操作代号\n");}}}
1 0
- 数据结构(二叉树子系统:c语言实现)
- 【数据结构】数据结构C语言的实现(简单二叉树)
- (C语言)二叉树实现(数据结构十三)
- [数据结构]C语言二叉树的实现
- c语言实现二叉树数据结构
- C语言二叉树的数据结构实现
- 数据结构:二叉查找树(C语言实现)
- 数据结构—二叉树(C语言实现)
- 二叉查找树 - C语言实现(摘自数据结构与算法分析 C语言描述)
- 二叉查找树 - C语言实现(摘自数据结构与算法分析 C语言描述)
- 数据结构(线性表子系统:c实现)
- 数据结构(循环队列子系统:c实现)
- 数据结构(栈子系统:c实现)
- C语言数据结构实现二叉树递归与非递归遍历(数据结构第四次实验)
- C语言-数据结构-二叉树
- 数据结构C语言实现系列[7]——二叉树
- 数据结构C语言实现系列——二叉树
- 数据结构C语言实现系列——二叉树[转]
- 理解JavaScript中的闭包
- 祝你幸福
- PhpWord 如何输出换行符到 word?
- Ubuntu Server 15.10中文环境乱码解决办法,亲测成功
- Code First模式初识
- 数据结构(二叉树子系统:c语言实现)
- Java实现文件复制
- c#实验5.5:接口的使用
- Dubbo java.io.IOException: Can not lock the registry cache file
- 自定义控件之对现有控件拓展(一)
- MFC双缓冲绘图
- 数据结构中的赫夫曼树编码,KMP算法,图的深度优先遍历和广度优先遍历
- PHP字符串组合递归
- Unity3D 重力下打飞碟