二叉树定义:在计算机科学中,二叉树是每个结点最多有两个子树的树结构。通常子树被称作“左子树”(left subtree)和“右子树”(right subtree)。二叉树常被用于实现二叉查找树和二叉堆。
详见:百度百科——二叉树
本文主要是介绍二叉树的创建,建立二叉树首先要创建 根结点 并对根结点 赋初值
然后,根据需要增加二叉树的结点,依据数据条件,按照规则增加二叉树的左子树或者右子树
最后,二叉树的遍历--输出二叉树的内容,这里可以分为前序遍历、中序遍历、后序遍历
本文代码实现了以下几点功能
1、创建二叉树,先创建根结点,未创建结点时自动修正未创建结点,根结点可以认为是只有一个结点的二叉树;
放弃已有的二叉树,重新创建;
2、增加已有二叉树的结点,对于已有的二叉树,可以随时选择增加结点;
增加结点时,可以依据判定条件,确定是否增加新的结点(已经存在的数据,不增加结点,只增加结点内容计数)
统计实际增加的结点数量,在增加结束后,输出实际增加的结点数量;
3、遍历二叉树,依序输出二叉树结点内容,输出二叉树结点数量
4、查找二叉树,并输出对应结点的信息
5、循环
二叉树的建立和遍历过程都是自引用循环,不需要而外的循环条件,否则容桂陷入陷入死循环;
代码如下:
#include "stdio.h"
#include "stdlib.h"
#include "string.h"
#include "windows.h"
struct stdu
{
int data;
int count;
struct stdu *pleft;
struct stdu *pright;
} ;
/*函数声明*/
int mean_s(struct stdu *roots);//功能目录,循环
void add_s(struct stdu *p);//增加结点
struct stdu *creact_s(int dv);//创建结点
int insert_s(struct stdu *ptem,struct stdu *r);//插入结点
int traverse_s(struct stdu *p);//遍历并输出所有结点
struct stdu *find_s(struct stdu *p,int fdv);//查找指定结点
int sum_s=0;//计数器初始化
/*创建结点*/
struct stdu *creact_s(int dv)
{
struct stdu *p;
//为新结点申请空间
if((p=(struct stdu *)malloc(sizeof(struct stdu)))==NULL)
{
printf("Sorry 分配内存失败!");
exit(0);
}
p->pleft=p->pright=NULL;
p->data=dv;//赋值
p->count=1;//结点计数
}
/*插入结点*/
int insert_s(struct stdu *ptem,struct stdu *r)
{
/*按照数据的情况,确定插入的位置*/
if(ptem->data==r->data)//数据已经存在,则不增加新结点,计数 +1
{
ptem->count++;
free(r);
return 0;
}
//数据不存在,先比较后增加新结点,左增加 或者右增加
else if(ptem->data>r->data)//左增加
{
if(ptem->pleft==NULL)
{
ptem->pleft=r;
sum_s++;
return 0;
}
else
insert_s(ptem->pleft,r);//左循环
}
else if(ptem->data<r->data)//右增加
{
if(ptem->pright==NULL)
{
ptem->pright=r;
sum_s++;
return 0;
}
else
insert_s(ptem->pright,r);//右循环
}
}
/*遍历二叉树-前序输出*/
int traverse_s1(struct stdu *p)
{
if(p->pleft!=NULL)
{
traverse_s1(p->pleft);
}
//如果带循环则按照计数总数输出,不带循环则按照结点数输出
//for(i=1;i<=p->count;i++)
{
printf(" %d--%d\n",p->data,p->count);
sum_s++;//统计二叉树结点数量
}
if(p->pright!=NULL)
{
traverse_s1(p->pright);
}
fflush(stdin);
}
/*遍历二叉树-中序输出*/
int traverse_s2(struct stdu *p)
{
{
printf(" %d--%d\n",p->data,p->count);
sum_s++;//统计二叉树结点数量
}
if(p->pleft!=NULL)
{
traverse_s2(p->pleft);
}
if(p->pright!=NULL)
{
traverse_s2(p->pright);
}
fflush(stdin);
}
/*遍历二叉树--后续输出*/
int traverse_s3(struct stdu *p)
{
if(p->pleft!=NULL)
{
traverse_s3(p->pleft);
}
if(p->pright!=NULL)
{
traverse_s3(p->pright);
}
{
printf(" %2d--%2d\n",p->data,p->count);
sum_s++;//统计二叉树结点数量
}
fflush(stdin);
}
struct stdu *pm=NULL;//标记查找到的结点
/*查找二叉树*/
struct stdu *find_s(struct stdu *p,int fdv)
{
if(p->data==fdv)
{
pm=p;//标记找到结点
sum_s++;//找到计数
}
if(p->pleft!=NULL) //便利查找左子树
find_s(p->pleft,fdv);
if(p->pright!=NULL) //便利查找右子树
find_s(p->pright,fdv);
return pm;//返回查找到的结点
}
/*增加结点*/
void add_s(struct stdu *roots)
{
int dv;//创建新结点,数据值
printf("\n*****增加新的结点*****\n");
printf("***输入名字\n\t输入 -1 结束***\n\n");
while(dv!=-1)//循环创建、插入结点
{
struct stdu *r;
scanf("%d",&dv);
if(dv==-1) //退出条件
break;
r=creact_s(dv);
insert_s(roots,r);
}
if(sum_s>0)
printf("\n*****增加了 %d 个新结点*****\n\n",sum_s);
else
printf("\n\t输入已经存在,没有增加新结点\n\n");
sum_s=0;//计数器归零
mean_s(roots);
}
/*功能目录,循环控制*/
int count=0;//已有二叉树计数
int mean_s(struct stdu *roots)
{
printf("【0】退出\n【1】创建新二叉树\n【2】增加结点\n");
printf("【3】查找指定结点\n【4】查看全部信息\n\n");
printf("选项: ") ;
struct stdu *pfind=NULL;
int dv;
fflush(stdin);//清除缓存
char c=getchar();//接收任意选择
int i_se=c-'0';//转换为数字
if(i_se!=0)
if(count==0&&i_se!=1)
{
printf("\n请先创建二叉树.....\n\n");
i_se=1;
}
switch(i_se)
{
case 0: system("pause");//退出
exit(0);
case 1: if(count==0)
{
count++;//创建新二叉树
return 0;
}
else
{
count=0;//
char c;
printf("创建新的二叉树: y?n\n");
fflush(stdin);
scanf("%c",&c);
if(c=='y'||c=='Y')
{
main();
}
else
mean_s(roots);
}
case 2: add_s(roots);//增加结点
break;
case 3: printf("\n***查找指定结点\n\t请输入名字***\n\n");
scanf("%d",&dv);
pfind=find_s(roots,dv);//查找指定结点,输出信息
if(sum_s>0)
printf("\n***找到结点: %d--%d ****\n\n",pfind->data,pfind->count);
else
printf("\n***Sorry 未找到。。。\n\n");
sum_s=0;//计数器归零
mean_s(roots);
case 4: printf("\n");
printf("*******二叉树结点信息******\n\n");
printf("\n***前序输出***\n\n");
traverse_s1(roots);//遍历二叉树,输出所有结点信息
printf("\n***中序输出***\n\n");
traverse_s2(roots);
printf("\n***后序输出***\n\n");
traverse_s3(roots);
printf("\n*****该二叉树有 %d 个结点****\n\n",sum_s/3);
sum_s=0;//计数器归零
mean_s(roots);
default :
printf("\n***输入错误...\n\n") ;
mean_s(roots);
}
system("pause");
}
/*主函数*/
int main()
{
printf("******二叉树的建立、增加和遍历*****\n\n");
int dv;
struct stdu *roots;
mean_s(roots); //进入程序功能目录
printf("\n***创建根结点\n\t请输入名字***\n\n");
scanf("%d",&dv);
roots=creact_s(dv);//创建根结点
printf("\n");
mean_s(roots); //进入程序菜单目录
system("pause");
return 0;
}