二叉树:创建、增加结点(任意)、遍历、查找

二叉树定义:在计算机科学中,二叉树是每个结点最多有两个子树的树结构。通常子树被称作“左子树”(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;
}

 

 

 

 

 

 

 

 

  • 1
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值