您的位置:首页 > 编程语言 > C语言/C++

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

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

#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");
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐