数据结构实验之查找二:平衡二叉树
Time Limit: 400 ms
Memory Limit: 65536 KiB
Problem Description
根据给定的输入序列建立一棵平衡二叉树,求出建立的平衡二叉树的树根。
Input
输入一组测试数据。数据的第1行给出一个正整数N(n <= 20),N表示输入序列的元素个数;第2行给出N个正整数,按数据给定顺序建立平衡二叉树。
Output
输出平衡二叉树的树根。
Sample Input
5 88 70 61 96 120
Sample Output
70
Hint
Source
xam
代码如下
#include <bits/stdc++.h>
#define typedata int
using namespace std;
typedef struct node
{
typedata data,high;
node * l,*r;
}*trie;
int deep(node *t)
{
if(t==NULL)return -1;
return t->high;
}
node* LL(node*t)
{
node *q=t->l;
t->l=q->r;
q->r=t;
t->high=max(deep(t->l),deep(t->r))+1;
q->high=max(deep(q->r),deep(q->l))+1;
return q;
}
node *RR(node*t)
{
node *q=t->r;
t->r=q->l;
q->l=t;
t->high=max(deep(t->l),deep(t->r))+1;
q->high=max(deep(q->l),deep(q->r))+1;
return q;
}
node *LR(node *t)
{
t->l=RR(t->l);
return LL(t);
}
node *RL(node *t)
{
t->r=LL(t->r);
return RR(t);
}
void creat(trie &t,int n)
{
if(t==NULL)
{
t=new node;
t->data=n;
t->high=0;
t->l=t->r=NULL;
}
else if(t->data>n)
{
creat(t->l,n);//先插入再判断;
if(deep(t->l)-deep(t->r)==2)
{
if(n<t->l->data)
t=LL(t);//进行右旋操作
else t=LR(t);
}
}
else
{
creat(t->r,n);
if(deep(t->l)-deep(t->r)==-2)
{
if(n>t->r->data)
t=RR(t);//(1)
else t=RL(t);//(2)
}
}
t->high=max(deep(t->l),deep(t->r))+1;
}
int main()
{
int n,c;
node*root=NULL;
scanf("%d",&n);
while(n--)
{
scanf("%d",&c);
creat(root,c);
}
printf("%d\n",root->data);
return 0;
}
AVL树相比于二叉搜索树多了LL,RR,LR,RL这几种操作,其目的是为了让二叉搜索树在特殊条件下不变成链表的线性结构,提高搜索效率
如果一棵二叉搜索树是高度平衡的,它就是AVL树,如果它有n个结点,其高度可保持在0(lgn),平衡搜索时间复杂度为O(lgn)
平衡化旋转:
如果在一棵原本是平衡的二叉搜索树中新插入一个结点,可能造成二叉搜索树的不平衡,此时必须调整树的结构,使之平衡化
以下示例简单描述了AVL树的2种操作:
先进行插入操作,然后观察到整个二叉搜索树不平衡且右儿子的深度比左儿子深,于是进行左单旋操作对应代码中的(1)处;
若插入操作完成后插入的是右儿子的左儿子的位置,即t->r->data<n; 那么进行RL操作,即将右儿子右单旋后左单旋;对应代码中的(2)处;
LL 与LR操作类似;其他与二叉搜索树不同的是引入了deep,它能够判断树的深度来判断是否平衡;