平衡二叉树实现

平衡因子:左子树和右子树高度差。用HB(k)表示。每一个节点都有这么一个平衡因子。
AVL中所有节点的HB(k)的绝对值不大于1
AVL树最少节点高度:
设AVL树高h,N(h)表示树高为h的AVL树的节点数。最少节点数出现在这种情况下:
左子树高为h-1,右子树高为h-2.<==>N(h)=N(h-1)+N(h-2)+1;<==>h=1.44logn
AVL树最多节点高度:
N(h)=2N(h-1)+1<==>h=logn
插入删除操作会使得AVL树的高度增加1或减少1.若AVL树的性质在节点X遭到破坏,则表明X的左子树与右子树的高度差为2.需要对节点X进行旋转操作。每次旋转操作能够使得X的高度减1。所以只需要对节点X进行旋转即可。
LL旋转:节点X的平衡因子为2的时候进行的操作。
将(X的左子树)的右子树作为X的左子树。将X作为(X的左子树)的右子树。
RR旋转:节点X的平衡因子为-2的时候进行的操作。
将(X的右子树)的左子树作为X的右子树。将X作为(X的右子树)的左子树。
LR旋转:节点X的左子树的右子树多了一个节点导致了不平衡。先对X的左子树进行RR旋转,问题变为了LL旋转的问题了。然后对X进行LL旋转

RL旋转:节点X的右子树的左子树多了一个节点导致了不平衡。先对X的右子树进行LL旋转,问题变为了RR旋转的问题了。然后对X进行RR旋转。

func.cpp

#include <cstdio>
#include "avl.h"
inline int max(int x,int y){
	if(x>y)return x;
	return y;
}
int height(AVL* root){
	if(!root)return -1;
	return root->h;
}
/*AVL旋转操作*/
AVL* singleRotateLL(AVL* root){
	AVL* left=root->left;
	root->left=left->right;
	left->right=root;
	root->h=max(height(root->left),height(root->right))+1;
	left->h=max(height(left->left),height(left->right))+1;
	return left;
}
AVL* singleRotateRR(AVL* root){
	AVL* right=root->right;
	root->right=right->left;
	right->left=root;
	root->h=max(height(root->left),height(root->right))+1;
	right->h=max(height(right->left),height(right->right))+1;
	return right;
}
AVL* doubleRotateLR(AVL* root){
	root->left=singleRotateRR(root->left);
	return singleRotateLL(root);
}
AVL* doubleRotateRL(AVL* root){
	root->right=singleRotateLL(root->right);
	return singleRotateRR(root);
}
/*AVL插入节点*/
AVL* insert(AVL* root,AVL* parent,int val){
	if(!root){
		root=new AVL(val,0,NULL,NULL);
	}
	else if(val<root->val){
		root->left=insert(root->left,root,val);
		if(height(root->left)-height(root->right)==2){
			if(val<root->left->val){
				root=singleRotateLL(root);
			}else{
				root=doubleRotateLR(root);
			}
		}
	}
	else if(val>root->val){
		root->right=insert(root->right,root,val);
		if(height(root->right)-height(root->left)==2){
			if(val>root->right->val){
				root=singleRotateRR(root);
			}else{
				root=doubleRotateRL(root);
			}
		}
	}
	root->h=max(height(root->left),height(root->right))+1;
	return root;
}
int find(AVL* root,int val){
	if(!root)return -1;
	if(root->val==val)return val;
	if(val<root->val)return find(root->left,val);
	return find(root->right,val);
}
AVL* findMin(AVL* root){
	if(root==NULL)return NULL;
	while(root->left){
		root=root->left;
	}
	return root;
}
AVL* deleteAVL(AVL* root,int val){
	if(!root)return NULL;
	else if(val<root->val){
		root->left=deleteAVL(root->left,val);
	//	printf("%d %d",height(root->right),height(root->left));
		if(height(root->right)-height(root->left)==2){
			if(height(root->right->left)>height(root->right->right)){
				root=doubleRotateRL(root);
			}else 
				root=singleRotateRR(root);
		}
	}
	else if(val>root->val){
		root->right=deleteAVL(root->right,val);
		if(height(root->left)-height(root->right)==2){
			if(height(root->left->left)>height(root->left->right)){
				root=singleRotateLL(root);
			}else
				root=doubleRotateLR(root);
		}
	}
	else if(root->left&&root->right){
		AVL* tmp=findMin(root->right);
		root->val=tmp->val;
		root->right=deleteAVL(root->right,tmp->val);
	}
	else
	{
		AVL* tmp=root;
		if(root->left){
			root=root->left;
		}else{
			root=root->right;
		}
		delete tmp;
	}
	if(root!=NULL){
		root->h=max(height(root->left),height(root->right))+1;
	}
	return root;
}


func.h

AVL* insert(AVL* root,AVL* parent,int val);
AVL* singleRotateRR(AVL* root);
AVL* singleRotateLL(AVL* root);
AVL* doubleRotateLR(AVL* root);
AVL* doubleRotateRL(AVL* root);
int find(AVL* root,int val);
AVL* deleteAVL(AVL* root,int val);

avl.h

class AVL{
	public:
		int val;
		int h;
		AVL* left;
		AVL* right;
		AVL(){}
		AVL(int val,int h,AVL* left,AVL* right){
			this->val=val;
			this->h=h;
			this->left=left;
			this->right=right;
		}
};
		



main.cpp

#include <cstdio>
#include <queue>
#include "avl.h"
#include "func.h"
using namespace std;
void show(AVL* root,AVL* base){
	queue<AVL*> q;
	q.push(root);
	q.push(NULL);
	while(!q.empty()){
		AVL* root=q.front();
		q.pop();
		if(!root){
			printf("\n");
			if(q.empty())break;
			q.push(NULL);
			continue;
		}
		if(root->val==-1){
			printf(" ");
			continue;
		}
		printf("%d ",root->val);
		if(root->left)q.push(root->left);
		else q.push(base);
		if(root->right)q.push(root->right);
		else q.push(base);
	}
}
int main(){
	int n,x,m;
	while(scanf("%d%d",&n,&m)!=EOF){
		AVL *root=NULL,*base=new AVL(-1,0,NULL,NULL);
		for(int i=0;i<n;i++){
			scanf("%d",&x);
			root=insert(root,NULL,x);
		}
		show(root,base);
		for(int i=0;i<m;i++){
			scanf("%d",&x);
			int val=find(root,x);
			printf("%d\n",val);
		}
		while(scanf("%d",&x)!=EOF){
			root=deleteAVL(root,x);
			show(root,base);
		}
	}
	return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值