二叉树的基本运用1

这篇文章详细介绍了如何使用C++实现二叉树的各种操作,包括从括号表示的字符串创建二叉树、销毁二叉树、查找节点、获取节点的孩子、计算树的高度、输出树的结构、统计节点数量、计算双分支和单分支节点个数、计算宽度以及寻找两个节点的最近公共祖先。
摘要由CSDN通过智能技术生成
#include<bits/stdc++.h>

using namespace std;

#define MaxSize 100
#define ElemType char 



typedef struct node
{
	ElemType data;//数据元素 
	
	struct node *lchild;//指向左孩子结点 
	
	struct node *rchild;//指向右孩子结点 
	
}BTNode;

//1.创建二叉树 
void CreateBTree(BTNode *&b , char *str)//
{
	BTNode *St[MaxSize],*p;//St数组作为顺序栈 
	
	int top=-1,k,j=0; //top 为栈顶指针 

	char ch;
	
	b = NULL;//初始时候二叉链表为空 
	
	ch = str[j];
	
	while(ch!='\0')
	{
		switch(ch)//遍历str中的每一个字符 
		{
			case '(' : top++;St[top] = p;k=1;break;	//开始处理左孩子结点 
			
			case ')' : top--;break;					//栈顶处理完毕 退栈 
			
			case ',' : k=2;break;					//开始处理右结点 
			
			default : p = new BTNode ;   			//创建一个结点 
			
			p->data = ch;//存放结点值
			
			p->lchild = p->rchild = NULL; //左右都初始化为空 
			
			if(b==NULL) //如果还没有存放根节点 
			{
				b = p;
			} 
			else
			{
				switch (k)
				{
					case 1:St[top]->lchild = p;break; //创建新结点作为栈顶的左节点 
					case 2:St[top]->rchild = p;break; //创建新结点作为栈顶的右节点 
				}
			}
			
			
			
		}
		
		j++;
		ch = str[j];
	}



	
 } 

//2.销毁二叉树
void DestoryBTree(BTNode *&b)
{
	if(b!=NULL)
	{
		DestoryBTree(b->lchild);
		DestoryBTree(b->rchild);
		delete b;
	 } 
	
 } 

//3.查找结点
BTNode *FindNode(BTNode *b,ElemType x)
{
	BTNode *p;
	
	if(b==NULL)//当前顶点是空 就返回NULL 
	{
		return NULL;
	}
	else if(b->data == x)//当前顶点是x 就返回这个值 
	{
		return b;
	}
	else				//当前顶点不是x 且存左右结点 
	{
		p = FindNode(b->lchild,x);//先去左孩子找x
		
		if(p!=NULL)//找到答案了就返回 
		{
			return p;
		}
		 
		else return FindNode(b->rchild,x); 
		 
	}

	
	
 } 

//4.找孩子结点
BTNode *LchildNode(BTNode *p) //返回结点p的左孩子结点地址 
{
	return p->lchild;
}
 
BTNode *RchildNode(BTNode *p) //返回结点p的左孩子结点地址 
{
	return p->rchild;
}

//5.求高度
int BTHeight(BTNode *b)
{
	int lchildh,rchildh;
	
	if(b==NULL) return (0);//空树的高度为0 
	
	else 
	{
		//某个顶点左右两边的高度 
		lchildh = BTHeight(b->lchild);//求左子树的高度
		
		rchildh = BTHeight(b->rchild);//求右子树的高度
		
		return (lchildh > rchildh) ? (lchildh + 1) : (rchildh + 1);
	 } 
	
	
 } 

//6.输出二叉树
void DispBTree(BTNode *b)
{
	if(b!=NULL)
	{
		printf("%c",b->data);
		
		if(b->lchild!=NULL || b->rchild!=NULL)
		{
			printf("(");
			DispBTree(b->lchild);
			
			if(b->rchild!=NULL) printf(",");
			
			DispBTree(b->rchild);
			
			printf(")");
			
		}
		
	}
	
	
	
 } 

//7.查找二叉树的节点个数(遍历每一个节点)
int FindOrder(BTNode *b)
{
	
	if(b!=NULL)
	{
		return FindOrder(b->lchild) + FindOrder(b->rchild) + 1;
	}
	else 
	return 0;
}

//8.输出该二叉树双分支结点的个数 	
int DoubleOrder(BTNode *b)
{
	
	
	
	if(b!=NULL&&b->lchild!=NULL && b->rchild!=NULL)//同时存在双节点 
	{
		int sum = 1;
		sum	+= DoubleOrder(b->lchild) ;
		
		sum += DoubleOrder(b->rchild) ;
		return sum;
	}
	else if(b!=NULL&&(b->lchild==NULL || b->rchild==NULL))	//没有同时存在双节点 
	{
		int sum =0;
		sum	+= DoubleOrder(b->lchild) ;
		
		sum += DoubleOrder(b->rchild) ;
		return sum;
	}
	else return 0;//当结点是空结点的时候返回0 
	
}

//9.输出该二叉树单分支结点的个数
int FindOne(BTNode *b)
{
	
	if(b!=NULL&&b->lchild!=NULL && b->rchild!=NULL)//同时存在双节点 
	{
		int sum = 0;
		sum	+= FindOne(b->lchild) ;
		
		sum += FindOne(b->rchild) ;
		return sum;
	}
	else if(b!=NULL && b->lchild==NULL && b->rchild!=NULL)	//没有同时存在双节点 
	{
		int sum = 1;
		sum	+= FindOne(b->lchild) ;
		
		sum += FindOne(b->rchild) ;
		return sum;
	}
	else if(b!=NULL&&b->lchild!=NULL && b->rchild==NULL)	//没有同时存在双节点 
	{
		int sum = 1;
		sum	+= FindOne(b->lchild) ;
		
		sum += FindOne(b->rchild) ;
		return sum;
	}
	else return 0;//什么都不存在 
 } 

//10.求宽度 
int Wide(BTNode *b)
{
	if(b==NULL) return 0;
	else 
	{
		BTNode *Q[FindOrder(b)];//Q是队列,元素为二叉树结点的指针,容量足够大
		
		int front=1,rear=1,last=1;//对头指针、队尾指针、last为最右结点在队列中的位置
		
		int res=0,maxw=0; //res记局部宽度,maxw记最大宽度
		
		Q[rear]=b;//根节点先入队 
		
		while(front<=last)
		{
			BTNode *p=Q[front++];//先赋值在出队 
			
			res++;//同层元素加一 
			
			if(p->lchild!=NULL) Q[++rear] = p->lchild;//左结点入队 
			if(p->rchild!=NULL) Q[++rear] = p->rchild;//右结点入队 
			
			if(front>last)//某一层结束 
			{
				last = rear;
				if(res>maxw) maxw = res;
				res=0;
			} 
			
			
		}
				
		return maxw;
	}

	
	
	
}

//11.任意给定该二叉树的两个结点,输出它们的最近的公共祖先
//(左右中--后序遍历 + dfs)
BTNode *Find(BTNode *root,ElemType p,ElemType q)
{
	if(root==NULL || root->data==p || root->data==q) return root;
	
	BTNode *left = Find(root->lchild,p,q);//看看root左边有没有p或者q 
	
	BTNode *right = Find(root->rchild,p,q);//看看root右边有没有p或者q 
	
	if(left!=NULL && right!=NULL) return root;//一直往上面返回 
	
	if(left==NULL && right!=NULL ) return right; //右边存在返回右边 
	
	if(left!=NULL && right==NULL ) return left;//左边存在返回左边 
	
}


int main()
{
	BTNode *b,*p;
	
	//1.创建该二叉树 
	ElemType str[]={"A(B(D,E(H(J,K(L,M(,N))))),C(F,G(,I)))"};
	CreateBTree(b,str);
	
	cout<<"二叉树btree:\n";
	DispBTree(b);
	
	//2.输入某个结点的左右结点 
	ElemType x;
	cout<<"\n请输入一个结点的值:";cin>>x;	
	p = b;
	if(FindNode(p,x) == NULL )
	{
		cout<<"\n你输入的结点值不存在!"<<endl;
	}
	else 
	{
		BTNode *q = FindNode(p,x);
		
		if(LchildNode(q)!=NULL)
		printf("左节点的值为%c\n\n",LchildNode(q)->data);
		else printf("左节点为NULL\n\n"); 
		
		if(RchildNode(q)!=NULL)
		printf("右节点的值为%c\n\n",RchildNode(q)->data);
		else printf("右节点为NULL\n\n");
	}
	
	
	//3.输出该二叉树的高度 
	printf("该二叉树的高度为:%d\n",BTHeight(b));cout<<endl;
	
	//4.输出该二叉树的结点个数 
	printf("该二叉树的结点个数%d个\n",FindOrder(b));cout<<endl;
	
	//5.输出该二叉树双分支结点的个数 
	printf("该二叉树的双分支结点个数%d个\n",DoubleOrder(b));cout<<endl;
	
	//6.输出该二叉树单分支结点的个数 
	printf("该二叉树的单分支结点个数%d个\n",FindOne(b));cout<<endl;
	
	//7.输出该二叉树叶子结点的个数。
	printf("该二叉树叶子结点的个数为%d个\n",FindOrder(b)-DoubleOrder(b)-FindOne(b));cout<<endl;
	
	//8.输出该二叉树的宽度
	printf("输出该二叉树的宽度%d\n",Wide(b)); cout<<endl;
	
	//9.任意给定该二叉树的两个结点,输出它们的最近的公共祖先
	//(上中下后序遍历 + dfs)
	ElemType n,m;
	printf("输入你要查找的两个结点");cin>>n>>m; 
	printf("输出这这个两个结点最近共同父结点是%c\n",Find(b,n,m)->data); cout<<endl;
	
	//10.摧毁二叉树
	
	DestoryBTree(b); 
	
	return 0;
} 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值