平衡二叉树的建立,查找,插入,调整,遍历的C语言实现

/*本程序实现了二叉树的建立,平衡,插入,查找,遍历
 由于平衡二叉树的删除非常复杂,这里就不做讨论了。
*/

#include<stdio.h>
#include<stdlib.h>
#define LH 1
#define EH 0
#define RH -1
typedef struct BinaryTree//定义二叉树的结构
{
	int data;//所要存储的数据
	struct BinaryTree *lchild;//左孩子
	struct BinaryTree *rchild;//右孩子
	int bf;//平衡因子
	int times;//同一个数据出现的次数
}BT,*pBT;
void R_router(pBT *T)//右旋转
{
	pBT lc=(*T)->lchild;
	(*T)->lchild=lc->rchild;
	lc->rchild=(*T);
	(*T)=lc;
}

void L_router(pBT *T)//左旋转
{
	pBT rc=(*T)->rchild;
	(*T)->rchild=rc->lchild;
	rc->lchild=(*T);
	(*T)=rc;
}

void LBalance(pBT *T)//左边调节
{
	pBT lc=(*T)->lchild;
	pBT lrc=(lc)->rchild;
	switch(lc->bf)
	{
	case EH:
		 {
			 lc->bf=EH;
			 (*T)->bf=EH;
			 R_router(T);	 		    
		 } 
		break;
	case RH:
		 {
			 
			switch(lrc->bf)
			{
				case LH:
					{
						lc->bf=EH;
						(*T)->bf=RH;
						lrc->bf=EH;
					}break;
				case EH:
					{
						lc->bf=EH;
						(*T)->bf=EH;
						lrc->bf=EH;
					}break;
				case RH:
					 {
						lc->bf=LH;
						(*T)->bf=EH;
						lrc->bf=EH;
					 }break;

					 
			}
			L_router(&(*T)->lchild);	//以左孩子为中心,先做一次左旋转	
			R_router(T);   //再以根节点为中心,做一次右旋转
		 }		
	}
}

void RBalance(pBT *T)//右边调节
{
	pBT rc=(*T)->rchild;
	pBT rlc=rc->lchild;
	switch(rc->bf)
	{
	case RH:
		 {
			 rc->bf=EH;
			 (*T)->bf=EH;
			 
			 L_router(T);
		 }break;
	case LH:
		 {
			 switch(rlc->bf)
			 {
			 case LH:
				  {
						rlc->bf=EH;
						(*T)->bf=EH;
						rc->bf=RH;
				  }break;
			 case EH:
				  {
						rlc->bf=EH;
						(*T)->bf=EH;
						rc->bf=EH;
				  }break;
			 case RH:
				  {
					  	rlc->bf=EH;
						(*T)->bf=LH;
						rc->bf=EH;
				  }break;
			 }
		 R_router(&(*T)->rchild);//以右孩子为中心,先做一次右旋转
		 L_router(T);//再以根节点为中心,做一次右旋转
		 }	
		
	}
}

int insert(pBT *T,int data,int *taller)//插入节点
{
	
	if((*T)==NULL)//当前节点为空,则插入
	{
		*taller=1;
		(*T)=(pBT)malloc(sizeof(BT));
		(*T)->bf=0;
		(*T)->data=data;
		(*T)->lchild=(*T)->rchild=NULL;
		(*T)->times=1;
		return 1;
	}
	if((*T)!=NULL)
	{
	  if((*T)->data<data)//往右边插入
		{			
		if(insert(&(*T)->rchild,data,taller))//如果树变高了,
		{
			switch((*T)->bf)
			{
			case LH:      //原来左边高,往右插入后,两边相等
				{
					*taller=0;
					(*T)->bf=EH;
				}break;
			
			case EH:	//原来相等,往右插入后,右子树高
				{
				
					*taller=1;
					(*T)->bf=RH;
				}break;
			case RH:	//原来为1,插入后变的更高,所以要调节
				{
					*taller=0;
					RBalance(T);
				}break;
			}
		}		
		}
		else if((*T)->data>data)//往左边插入
		{
			if(insert(&(*T)->lchild,data,taller))
			{
				switch((*T)->bf)
				{
					case LH:    //原来为1,插入后变的更高,所以要调节
						{
							LBalance(T);
							*taller=0;
						}break;
					case EH:		//原来相等,插入后,左子树变高
						{
							*taller=1;
							(*T)->bf=LH;
						}break;
					case RH:{		//原来右子树高,插入后,左右平衡
								*taller=0;
								(*T)->bf=EH;
							}break;
				}
			}
		}
		else if((*T)->data==data)//如果插入的数已经存在,则出现的次数+1,然后树高不变
		{
			(*T)->times++;
			*taller=0;
		}
	}
	return *taller;
}


int travel(pBT T)//中序遍历
{
	if(T)
	{
	
		travel(T->lchild);
		printf("%d ",T->data);
		travel(T->rchild);
	}
}

int find(int target,pBT T)
{
	int i=0;
	if(T)
	{
		if(T->data>target)
			i=find(target,T->lchild);
		else if(T->data<target)
			i=find(target,T->rchild);
		else if(T->data==target)
			return 1;
	}
	return i;
}
int main()
{
	int *taller,i=0,k=0;
	BT t,*T;
	pBT *P=NULL;	
	int a[12]={0,2,1,4,5,6,7,8,9,11,15,16};
	taller=&k;
	T=NULL;
	P=&T;
	for(i=0;i<12;i++)
	{
		insert(P,a[i],taller);
	}
	travel((*P));
	i=find(4,(*P));
	if(i==0)
		printf("\n\n没有出现4\n\n");
	else
		printf("\n\n出现了4\n\n");
}




		
    原文作者:二叉查找树
    原文地址: https://blog.csdn.net/u011918260/article/details/38389225
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞