啊啊啊啊,被折磨的遍体鳞伤,最后参考老师给的代码写出些来
所以坚持就是一定能看到希望,永远不能放弃
http://www.patest.cn/contests/mooc-ds/04-1
犯的错误:
1.
struct tree{
int data;
int left;
int right;
int height;
}t[MAX];
这里我用left,right存储的是数字,即左右孩子的值,而不是下标!后面忘记这个,一直再犯错
2.
原理问题:
int RR(int x){//传进来的是A,即最上面不平衡的点的下标
//先旋转,再更新高度,最后返回
int rl=findi(t[x].right);//找到B的下标
t[x].right=t[rl].left;//A的右是B的左
t[rl].left=t[x].data;//B的左是A的
t[x].height=max(gethei(findi(t[x].left)),gethei(findi(t[x].right)))+1;//更新A的高度,A左和A右
t[rl].height=max(t[x].height,gethei(findi(t[rl].right)))+1;//更新B的高度,A和B右
return rl;
}
int LL(int x){
int xl=findi(t[x].left);
t[x].left=t[xl].right;
t[xl].right=t[x].data;
t[x].height=max(gethei(findi(t[x].left)),gethei(findi(t[x].right)))+1;
t[xl].height=max(gethei(findi(t[xl].left)),t[x].height)+1;
return xl;
}
对于LR应该先将左孩子RR,再将自己LL
错误一:RR和LL函数得到是下标
错误二: 先将左孩子RR表示用RR方式改变A的左孩子
int LR(int x){
//先左孩子RR
int xl=findi(t[x].left);
//错误一:xl=RR(xl);
//错误二:得到的是下标t[x].left=RR(xl);
//改变左孩子,而不是左孩子的值t[xl].data=RR(xl);
t[x].left=t[RR(xl)].data;
//再节点LL
return LL(x);
}
int RL(int x){
//先右孩子LL
int rl=findi(t[x].right);
//t[x].right=LL(rl);
//t[rl].data=LL(rl);
t[x].right=t[LL(rl)].data;
//再节点RR
return RR(x);
}
3.insert函数
a结点是空,就直接插入,对所有系数都要进行设置
b插入后还要进行高度测试,判断是否需要旋转
c更新树高!!!
d返回值,注意返回的是结点的值,而不是下标,因为结构开始就这样定义的
int insert(int x,int i){
if(t[i].data==-1){
t[i].data=x;
t[i].left=-1;
t[i].right=-1;
t[i].height=0;
}else if(x<t[i].data){
int li=findi(t[i].left);
int ri=findi(t[i].right);
t[i].left=insert(x,li);
//需要左旋
if(gethei(findi(t[i].left))-gethei(findi(t[i].right))==2){
//LL旋转
if(x<t[li].data){
i=LL(i);
}else{
//LR旋转
i=LR(i);
}
}
}else if(x>t[i].data){
int li=findi(t[i].left);
int ri=findi(t[i].right);
t[i].right=insert(x,ri);
//if(gethei(li)-gethei(ri)==-2){
if(gethei(findi(t[i].left))-gethei(findi(t[i].right))==-2){
if(x<t[ri].data){
//RL旋转
i=RL(i);
}else{
//RR旋转
i=RR(i);
}
}
}
//更新树高
t[i].height=max(gethei(findi(t[i].left)),gethei(findi(t[i].right)))+1;
return t[i].data;
}
完整代码
/*
title:04-1
问题分类:
*/
#include<stdio.h>
#define MAX 70
struct tree{
int data;
int left;
int right;
int height;
}t[MAX];
void init(){
for(int i=0;i<MAX;i++){
t[i].data=-1;
t[i].left=-1;
t[i].right=-1;
t[i].height=0;
}
}
int max(int a,int b){
return a<b?b:a;
}
int findi(int x){
for(int i=0;i<MAX;i++){
if(t[i].data==x){
return i;
}
}
}
int gethei(int x){
if(t[x].data!=-1){
int li=findi(t[x].left);
int ri=findi(t[x].right);
return max(gethei(li),gethei(ri))+1;
}else{
return 0;
}
}
//旋转输入的是最上面的不平衡节点的下标
int RR(int x){
//先旋转,再更新高度,最后返回
int rl=findi(t[x].right);
t[x].right=t[rl].left;
t[rl].left=t[x].data;
t[x].height=max(gethei(findi(t[x].left)),gethei(findi(t[x].right)))+1;
t[rl].height=max(t[x].height,gethei(findi(t[rl].right)))+1;
return rl;
}
int LL(int x){
int xl=findi(t[x].left);
t[x].left=t[xl].right;
t[xl].right=t[x].data;
t[x].height=max(gethei(findi(t[x].left)),gethei(findi(t[x].right)))+1;
t[xl].height=max(gethei(findi(t[xl].left)),t[x].height)+1;
return xl;
}
int LR(int x){
//先左孩子RR
int xl=findi(t[x].left);
//xl=RR(xl);
//t[x].left=RR(xl);
//t[xl].data=RR(xl);
t[x].left=t[RR(xl)].data;
//再节点LL
return LL(x);
}
int RL(int x){
//先右孩子LL
int rl=findi(t[x].right);
//t[x].right=LL(rl);
//t[rl].data=LL(rl);
t[x].right=t[LL(rl)].data;
//再节点RR
return RR(x);
}
int insert(int x,int i){
if(t[i].data==-1){
t[i].data=x;
t[i].left=-1;
t[i].right=-1;
t[i].height=0;
}else if(x<t[i].data){
int li=findi(t[i].left);
int ri=findi(t[i].right);
t[i].left=insert(x,li);
//需要左旋
if(gethei(findi(t[i].left))-gethei(findi(t[i].right))==2){
//LL旋转
if(x<t[li].data){
i=LL(i);
}else{
//LR旋转
i=LR(i);
}
}
}else if(x>t[i].data){
int li=findi(t[i].left);
int ri=findi(t[i].right);
t[i].right=insert(x,ri);
//if(gethei(li)-gethei(ri)==-2){
if(gethei(findi(t[i].left))-gethei(findi(t[i].right))==-2){
if(x<t[ri].data){
//RL旋转
i=RL(i);
}else{
//RR旋转
i=RR(i);
}
}
}
//更新树高
t[i].height=max(gethei(findi(t[i].left)),gethei(findi(t[i].right)))+1;
//return t[i].data;
return i;
}
int main(){
freopen("in.txt","r",stdin);
int zu;
while(scanf("%d",&zu)!=EOF){
init();
int root=0;
for(int i=0;i<zu;i++){
int x;
scanf("%d",&x);
root=insert(x,root);
}
printf("%d\n",t[root].data);
}
return 0;
}