代码思路与课本图示相同。
直接看代码:
#include<stdio.h>
#include<stdlib.h>
typedef struct TreeNode
{
struct TreeNode *parent,*lchild,*rchild;
int factor,data;
}TreeNode;//定义结点的类型,设置双亲结点以便查找
int num=0;
TreeNode*single1=NULL,*single2=NULL;//这两个指针用来指示最高层次中平衡因子为2或-2的结点的地址
TreeNode *T=NULL;
void Creat(TreeNode *H)
{//创建平衡树,依次输入根节点及其孩子等
TreeNode *p,*q;
if(!H)
{
H=(TreeNode *)malloc(sizeof(TreeNode));
H->parent=NULL;
printf("输入根节点: ");
scanf("%d",&H->data);
T=H;
}
printf("输入%d的左孩子: ",H->data);
int a_l,a_r;
scanf("%d",&a_l);
if(a_l)
{
p=(TreeNode *)malloc(sizeof(TreeNode));
H->lchild=p;
p->parent=H;
p->data=a_l;
Creat(p);
}
else
H->lchild=NULL;
printf("输入%d的右孩子: ",H->data);
scanf("%d",&a_r);
if(a_r)
{
q=(TreeNode *)malloc(sizeof(TreeNode));
H->rchild=q;
q->parent=H;
q->data=a_r;
Creat(q);
}
else
H->rchild=NULL;
}
int High(TreeNode *P)
{//计算树高,用来计算结点的平衡因子,采用递归调用的方法
int lefthigh=0,righthigh=0;
if(!P)
return 0;
else
{
lefthigh=High(P->lchild)+1;
righthigh=High(P->rchild)+1;
if(lefthigh>righthigh)
return lefthigh;
else
return righthigh;
}
}
void BalanceFactor(TreeNode *H)
{//求解平衡因子,采用递归调用,计算得到每个结点的平衡因子
void LXuanzhuan(TreeNode *A);
void RXuanzhuan(TreeNode *A);
if(H)
{int h1,h2;
h1=High(H->lchild);
h2=High(H->rchild);
H->factor=h1-h2;
if(H->factor>=2)
single1=H;
if(H->factor<=-2)
single2=H;//singel1和single2分别存放平衡因子为2和-2的结点的地址
BalanceFactor(H->lchild);
BalanceFactor(H->rchild);
}
}
void Insert(TreeNode H,int a)
{//插入元素
void LXuanZhuan(TreeNodeA);
void RXuanZhuan(TreeNode*A);
void PreOrder(TreeNode *H);
TreeNode *q,*p,*A,*B,*C,*Parent,*C_l,*C_r;
if(a<H->data)
{//如果该元素值小于结点,则应该在结点的左子树上
if(H->lchild)
Insert(H->lchild,a);//递归插入
else
{
q=(TreeNode *)malloc(sizeof(TreeNode));
q->data=a;
H->lchild=q;
q->parent=H;
q->lchild=q->rchild=NULL;
q->factor=0;//新建结点,填好它的双亲结点
}
}
else
{
//大于结点,则应该在这个结点的右子树上
if(H->rchild)
Insert(H->rchild,a);
else
{
p=(TreeNode *)malloc(sizeof(TreeNode));
p->data=a;
H->rchild=p;
p->parent=H;
p->lchild=p->rchild=NULL;
p->factor=0;
}
}
single1=single2=NULL;//每次计算所有结点的平衡因子,都应该先把这两个标记指针记为空
BalanceFactor(T);
PreOrder(T);//先序遍历该树
printf("\n");
//标记指针不为空,则应该进行旋转
if(single1)
{LXuanZhuan(single1);}
if(single2)
{RXuanZhuan(single2);}
}
void LXuanZhuan(TreeNode *A)
{//左旋转
void LXuanZhuan(TreeNode*A);
void RXuanZhuan(TreeNode*A);
void PreOrder(TreeNode *H);
TreeNode *B,*C,*Parent,*C_l,*C_r;
Parent=A->parent;
B=A->lchild;
if(B->factor==1)
{
B->parent=A->parent;
if(Parent)
{
if(Parent->lchild==A)
Parent->lchild=B;
else
Parent->rchild=B;
}
else
T=B;
A->parent=B;
if(B->rchild)
B->rchild->parent=A;
A->lchild=B->rchild;
B->rchild=A;
}
if(B->factor==-1)
{
C=B->rchild;
C->parent=A->parent;
if(Parent){
if(Parent->lchild==A)
Parent->lchild=C;
else
Parent->rchild=C;
}
else
T=C;
C_l=C->lchild;
C_r=C->rchild;
if(C_l)
C_l->parent=B;
if(C_r)
C_r->parent=A;
C->lchild=B;
C->rchild=A;
B->rchild=C_l;
A->lchild=C_r;
B->parent=C;
A->parent=C;//此处的个结点的关系很重要,如果不能正确写,找问题非常麻烦
}
single1=single2=NULL;
BalanceFactor(T);
PreOrder(T);
printf("\n");
if(single1)
LXuanZhuan(single1);
if(single2)
RXuanZhuan(single2);
}
void RXuanZhuan(TreeNode* A)
{//右旋转
void LXuanZhuan(TreeNodeA);
void RXuanZhuan(TreeNodeA);
void PreOrder(TreeNode *H);
TreeNode *B,*C,*Parent,*C_l,*C_r;
Parent=A->parent;
B=A->rchild;
if(B->factor==-1)
{
B->parent=A->parent;
if(Parent)
{
if(Parent->lchild==A)
Parent->lchild=B;
else
Parent->rchild=B;
}
else
{T=B;}
if(B->lchild)
B->lchild->parent=A;
A->parent=B;
A->rchild=B->lchild;
B->lchild=A;
}
if(B->factor==1)
{
C=B->lchild;
C->parent=A->parent;
if(Parent)
{
if(Parent->lchild==A)
Parent->lchild=C;
else
{Parent->rchild=C;
}
}
else
{T=C;}
C_l=C->lchild;
C_r=C->rchild;
if(C_l)
C_l->parent=A;
if(C_r)
C_r->parent=B;
C->lchild=A;
C->rchild=B;
B->lchild=C_r;
A->rchild=C_l;
B->parent=C;
A->parent=C;
}
single1=single2=NULL;
BalanceFactor(T);
PreOrder(T);
if(single1)
LXuanZhuan(single1);
if(single2)
RXuanZhuan(single2);
}
void PreOrder(TreeNode *H)
{//递归先序遍历AVL
if(H){
printf("%d(%d) ", H->data,H->factor);
PreOrder(H->lchild);
PreOrder(H->rchild);
}
}
int main()
{
printf("___________________________________________________\n");
printf(" 输入你想要进行的操作(0表示退出) \n");
printf(" 1:创建平衡二叉树 \n");
printf(" 2:插入元素 \n");
printf(" 3:查看二叉树 \n");
int k;
printf(“输入你想进行的操作: “);
scanf(”%d”,&k);
int a;
while(k!=0)
{
switch(k)
{
case 1:
Creat(T);
BalanceFactor(T);
PreOrder(T);
break;
case 2:
printf("输入你想要插入的元素: ");
scanf("%d",&a);
Insert(T,a);
break;
case 3:PreOrder(T);break;
}
printf("\n输入你想进行的操作: ");
scanf("%d",&k);
}
return 0;
}