04-1

啊啊啊啊,被折磨的遍体鳞伤,最后参考老师给的代码写出些来

所以坚持就是一定能看到希望,永远不能放弃

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;
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值