avl树实现

#include<stdio.h>
#include<stdlib.h>
//平衡树的实现




typedef struct AvlNode{
	int element;
	struct AvlNode *left;
	struct AvlNode *right;
	int height;
}*AvlTree;
int Height(AvlTree T){
	if(T==NULL){
		return -1;
	}else{
		return T->height;
	}
}

AvlTree SingleTotateWithLeft(AvlTree T);
AvlTree SingleTotateWithRight(AvlTree T);
AvlTree DoubleTotateWithLeft(AvlTree T);
AvlTree DoubleTotateWithRight(AvlTree T);

void print(AvlTree T){
	//先序遍历 根左右
	if(T){
		printf("%d ",T->element);
		print(T->left);
		print(T->right);
	}
	

	 
}



int Max(int k1,int k2){
	if(k1>k2){
		return k2;
	}else{
		return k1;
	}
}

//插入
AvlTree Insert(int X,AvlTree T){
	 
	//分情况计论
	//树为空
	if(T==NULL){
		//生成一个新树
		T=(AvlTree)malloc(sizeof(struct AvlNode));
		T->element=X;
		T->left=NULL;
		T->right=NULL;
		T->height=0; 
	} 
	//不空 
	else if(X>T->element){
		//比树根元素大,到右子树
		 //将右边的子树当成一个新的树
		 T->right=Insert(X,T->right);
		 if(Height(T->left)-Height(T->right)==-2){
		 	//需要重新平衡 判断是右右还是右左 
		 	if(X>T->right->element){
		 		//右右 单旋
				 T=SingleTotateWithRight(T); 
		 	} else{
		 		//右左 双旋
				 T=DoubleTotateWithRight(T); 
		 	}
		 }
		  
	}else if(X<T->element){
		//比根元素小,到左子树 
		T->left=Insert(X,T->left);
		if(Height(T->left)-Height(T->right)==2){
			//需要重新平衡,判断是左左还是左右 
			if(X>T->left->element){
				//左右 双旋
				T=DoubleTotateWithLeft(T); 
			}else{
				//左左 单旋 
				T=SingleTotateWithRight(T);
			} 
		} 
	}
	
	T->height=Max(Height(T->left),Height(T->right))+1;
	
	return T;
} 
//左单旋 
AvlTree SingleTotateWithLeft(AvlTree T){
	//获取到T的左孩子
	AvlTree P=T->left;
	//p将成为新的结点,将其右孩子转为T的左孩子
	T->left=P->right;
	P->right=T;
	//旋转后高度重新处理
	T->height=Max(Height(T->left),Height(T->right))+1;
	P->height=Max(Height(T),Height(P->left))+1; 

	//返回P替代T
	return P; 
}
//右单旋
AvlTree SingleTotateWithRight(AvlTree T){
	//获取T右孩子
	AvlTree P=T->right;
	//p将成为新的结点,将其左孩子转为T的右孩子
	T->right=P->left;
	P->left=T;
	
	//旋转后重新处理高度
	T->height=Max(Height(T->left),Height(T->right))+1;
	P->height=Max(Height(T),Height(P->right))+1 ;
	
	
	//返回p代替T
	return P; 
} 
//左双旋
AvlTree  DoubleTotateWithLeft(AvlTree T){
	//获取的节点为高两层的节点
	//先进行左单旋 
	T->left=SingleTotateWithLeft(T->left);
	//再进行右单旋 
	return  SingleTotateWithRight(T); 
}
//右双旋
AvlTree DoubleTotateWithRight(AvlTree T){
	//获取的节点为高两层的节点
	//先进行右单旋
	T->right=SingleTotateWithRight(T->right);
	//再返回左单旋的结果
	return SingleTotateWithLeft(T); 
} 



//测试 
int main(){
	 AvlTree T=NULL;
	 T=Insert(4,T);
	 T=Insert(2,T);
	 T=Insert(6,T);
	 T=Insert(1,T);
	 T=Insert(3,T); 
	 T=Insert(5,T);
	 T=Insert(15,T);
	 T=Insert(7,T);
	 T=Insert(16,T);
	 T=Insert(14,T);
	 //打印出树的结果
	 print(T); 
	 
}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值