Problem Description
根据给定的输入序列建立一棵平衡二叉树,求出建立的平衡二叉树的树根。
Input
输入一组测试数据。数据的第1行给出一个正整数N(n <= 20),N表示输入序列的元素个数;第2行给出N个正整数,按数据给定顺序建立平衡二叉树。
Output
输出平衡二叉树的树根。
Sample Input
5
88 70 61 96 120
Sample Output
70
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
struct node
{
int data;
int deep;
struct node *l,*r;
};
int n;
int max(int a,int b)//比较大小函数
{
if(a>b)
return a;
else
return b;
}
int deept(struct node * root)//返回深度函数
{
if(root==NULL)
return 0;
return root->deep;
}
struct node * ll(struct node * p)//右旋,LL型
{
struct node * q=p->l;//q指向根的左子树的根节点
p->l=q->r;//左子树的根节点的右子树的根节点成为原根节点的左子树
q->r=p;//原来根节点变成左子树根节点的右子树根节点
p->deep=max(deept(p->l),deept(p->r))+1;//更改原根节点的深度
q->deep=max(p->deep,deept(q->l))+1;//更改现根节点的深度
p=q;//将q的值赋值给p,并且传出。
return p;
}
struct node * rr(struct node *p)
{
struct node *q=p->r;//q指向根节点的右子树的根节点
p->r=q->l;//将原左子树根节点的右子树根节点的左子树根节点变成原根节点的右子树根节点
q->l=p;//原根节点变成根节点的右子树的左子树的根节点。
p->deep=max(deept(p->l),deept(p->r))+1;//更新原根节点的深度
q->deep=max(deept(q->r),p->deep)+1;//更新现根节点的深度
p=q;
return p;
}
struct node * lr(struct node *p)
{
p->l= rr(p->l);//对左子树先进行右旋
return ll(p);//再进行左旋
}
struct node * rl(struct node *p)
{
p->r=ll(p->r);//对右子树先进行左旋
return rr(p);//再进行右旋
}
struct node * creat(struct node *root,int x)//建造平衡二叉树
{
if(root==NULL)//如果根是空的
{
root=(struct node *)malloc(sizeof(struct node));
root->data=x;
root->deep=1;
root->l=NULL;
root->r=NULL;
}
else if(x<root->data)//如果值小于根的当前值
{
root->l=creat(root->l,x);//进行左递归
if(deept(root->l)-deept(root->r)>1)//如果此时不满足平衡二叉树
{
if(x<root->l->data)//如果输入的值小于最后一个节点的值,即为LL型。
root=ll(root);
else//如果不是则就是LR
root=lr(root);
}
}
else if(x>root->data)//同理判断是RR还是RL
{
root->r=creat(root->r,x);
if(deept(root->r)-deept(root->l)>1)
{
if(x<root->r->data)
root=rl(root);
else
root=rr(root);
}
}
root->deep=max(deept(root->l),deept(root->r))+1;//递归实现更新每个结点的深度
return root;
};
int main()
{
scanf("%d",&n);
struct node *root=NULL;
while(n--)
{
int x;
scanf("%d",&x);
root = creat(root,x);
}
printf("%d\n",root->data);
return 0;
}