AVL树【数据结构】

                                                        AVL树

一、介绍

AVL树是最先被发明的自平衡二叉查找树,也被称为高度平衡树。相比二叉查找树,它的特点是AVL树中任何结点的两个子树的高度差别最大为1。AVL树的查找、插入和删除在平均和最坏情况下都是O(logn)

 

二、原理

1、失去平衡的四种情况即相应的旋转操作

LL:根的左子树的左子树还有非空子结点,导致根的左子树的高度比根的右子树的高度大2

RR:根的右子树的右子树还有非空子结点,导致根的右子树的高度比根的左子树的高度大2

LR:根的左子树的右子树还有非空子结点,导致根的左子树的高度比根的右子树的高度大2

RL:根的右子树的左子树还有非空子结点,导致根的右子树的高度比根的左子树的高度大2

2、添加操作

//将键值为key结点插入AVL树中 
template<class T>
Node<T>* AVLTree<T>::insert(Node<T>* &tree,T key)
{
	if(!tree)
	{
		tree=new Node<T>(key,NULL,NULL);
		if(!tree)
		{
			cout<<"创建结点失败!"<<endl;
			return NULL;
		}
	}
	
	else if(key<tree->key)//key应该插入tree的左子树 
	{
		tree->l=insert(tree->l,key);
		//插入结点后,若AVL树失去平衡,则进行相应的调整
		if(height(tree->l)-height(tree->r)==2)
		{
			if(key<tree->l->key)
			  tree=LL(tree);
			else
			  tree=LR(tree); 
		} 
	}
	
	else if(key>tree->key)//key应该插入tree的右子树
	{
		tree->r=insert(tree->r,key);
		//插入结点后,若AVL树失去平衡,则进行相应的调整
		if(height(tree->r)-height(tree->l)==2)
		{
			if(key<tree->r->key)
			  tree=RL(tree);
			else
			  tree=RR(tree);
		} 
	}
	
	else
	{
		cout<<"不允添加相同的结点!"<<endl; 
	} 
	tree->h=max(height(tree->l),height(tree->r))+1;
	return tree;//返回根结点 
}

template<class T>
void AVLTree<T>::insert(T key)
{
	insert(root,key);
}

3、删除操作

//删除结点z 
template<class T>
Node<T>* AVLTree<T>::remove(Node<T>* &tree,Node<T> *z)
{
	//根为空或者没有要删除的结点,直接返回NULL
	if(!tree||!z) return NULL;
	if(z->key<tree->key)//待删除结点在tree的左子树中 
	{
		tree->l=remove(tree->l,z);
		//删除结点后,若AVL树失去平衡,则进行相应的调整
		if(height(tree->r)-height(tree->l)==2)
		{
			if(height(tree->r->l)>height(tree->r->r))
			  tree=RL(tree);
			else
			  tree=RR(tree);
		} 
	} 
	
	else if(z->key>tree->key)//待删除结点在tree的右子树中
	{
		tree->r=remove(tree->r,z);
		//删除结点后,若AVL树失去平衡,则进行相应的调整
		if(height(tree->l)-height(tree->r)==2)
		{
			if(height(tree->l->l)>height(tree->l->r))
			  tree=LL(tree);
			else
			  tree=LR(tree);
		} 
		
	}
	
	else//tree对应要删除的结点 
	{
		//tree的左右孩子都非空
		if(tree->l&&tree->r)
		{
			//tree的左子树比右子树高 
			if(height(tree->l)>height(tree->r))
			{
				//找出tree的左子树中的最大结点,将其键值赋给tree,然后删除它
				Node<T>* maxNode=maximum(tree->l);
				tree->key=maxNode->key;
				tree->l=remove(tree->l,maxNode); 
			}
			//tree的右子树的高度大于或等于左子树高度 
			else
			{
				//找出tree的右子树中的最小结点,将其键值赋给tree,然后删除它
				Node<T>* minNode=minimum(tree->r);
				tree->key=minNode->key;
				tree->r=remove(tree->r,minNode); 
			}
		}
		//tree的左右孩子只要有一个为空 
		else
		{
			Node<T>* tmp=tree;
			tree=(tree->l)?tree->l:tree->r;
			delete tmp;
		} 
	} 
	return tree; //返回根结点 
} 

template<class T>
void AVLTree<T>::remove(T key)
{
	Node<T> *z=search(root,key);
	if(z) root=remove(root,z);
} 

三、C++实现

#include<iostream>
#include<algorithm> 

using namespace std;

template<class T>
class Node{
	public:
		T key;//键值 
		int h;//高度 
		Node *l;//左孩子 
		Node *r;//右孩子 
		Node(T key,Node *l,Node *r):key(key),h(0),l(l),r(r){};
}; 

template<class T>
class AVLTree{
	private:
		Node<T> *root;//根结点
	//外部接口 
	public:
		AVLTree();
		~AVLTree();
		int height();//获取树的高度
		void preOrder();//前序遍历
		void inOrder();//中序遍历 
		void postOrder();//后序遍历 
		Node<T>* search(T key);//查找键值为key的结点(递归实现) 
		Node<T>* iterativeSearch(T key);//查找键值为key的结点(非递归实现)
		T minimum();//返回最小结点的键值
		T maximum();//返回最大结点的键值
		void insert(T key);//将建值为key的结点插入AVL树中
		void remove(T key);//删除键值为key的结点
		void destroy();//销毁AVL树
		void print();//打印AVL树
	
	//内部接口	
	private:
		int height(Node<T>* tree);//获取树的高度
		void preOrder(Node<T>* tree);//前序遍历
		void inOrder(Node<T>* tree);//中序遍历
		void postOrder(Node<T>* tree);//后序遍历 
		Node<T>* search(Node<T>* tree,T key);//查找键值为key的结点(递归实现) 
		Node<T>* iterativeSearch(Node<T>* tree,T key);//查找键值为key的结点(非递归实现)
		Node<T>* minimum(Node<T>* tree);//返回最小结点
		Node<T>* maximum(Node<T>* tree);//返回最大结点
		//旋转
		Node<T>* LL(Node<T>* root);//LL旋转 
		Node<T>* RR(Node<T>* root);//RR旋转 
		Node<T>* LR(Node<T>* root);//LR旋转 
		Node<T>* RL(Node<T>* root);//RL旋转
		
		Node<T>* insert(Node<T>* &tree,T key);//将键值为key的结点插入AVL树中 
		Node<T>* remove(Node<T>* &tree,Node<T> *z);//删除结点z
		 
		void destroy(Node<T>* &tree);//销毁AVL树
		void print(Node<T>* tree,T key,int child);//打印AVL树 
};

//构造函数
template<class T>
AVLTree<T>::AVLTree()
{
	root=NULL;
}

//析构函数
template<class T>
AVLTree<T>::~AVLTree()
{
	destroy(root);
}

//获取树的高度 内部接口
template<class T>
int AVLTree<T>::height(Node<T>* tree)
{
	if(tree) return tree->h;
} 

//获取树的高度 外部接口 
template<class T>
int AVLTree<T>::height()
{
	return height(root);
} 

//前序遍历
template<class T>
void AVLTree<T>::preOrder(Node<T> *tree)
{
	if(tree)
	{
		cout<<tree->key<<" ";
		preOrder(tree->l);
		preOrder(tree->r); 
	}
} 

template<class T>
void AVLTree<T>::preOrder()
{
	preOrder(root);
}

//中序遍历 
template<class T>
void AVLTree<T>::inOrder(Node<T> *tree)
{
	if(tree)
	{
		inOrder(tree->l);
		cout<<tree->key<<" ";
		inOrder(tree->r);
	}
}

template<class T>
void AVLTree<T>::inOrder()
{
	inOrder(root);
}

//后序遍历
template<class T>
void AVLTree<T>::postOrder(Node<T> *tree)
{
	if(tree)
	{
		postOrder(tree->l);
		postOrder(tree->r);
		cout<<tree->key<<" ";
	}
}

template<class T>
void AVLTree<T>::postOrder()
{
	postOrder(root);
}

//查找键值为key的结点(递归实现) 
template<class T>
Node<T>* AVLTree<T>::search(Node<T>* tree,T key)
{
	if(tree)
	{
		if(key<tree->key)
		  return search(tree->l,key);
		else if(key>tree->key)
		  return search(tree->r,key);
		return tree;
	}
	return NULL;
}

template<class T>
Node<T>* AVLTree<T>::search(T key)
{
	return search(root,key);
}

//查找键值为key的结点(非递归实现)
template<class T>
Node<T>* AVLTree<T>::iterativeSearch(Node<T>* tree,T key)
{
	while(tree&&tree->key!=key)
	{
		if(key<tree->key)
		  tree=tree->l;
		else
		  tree=tree->r;
	}
	return tree;
}

template<class T>
Node<T>* AVLTree<T>::iterativeSearch(T key)
{
	return iterativeSearch(root,key);
}

//返回最小结点
template<class T>
Node<T>* AVLTree<T>::minimum(Node<T> *tree)
{
	if(!tree) return NULL;
	while(tree->l) tree=tree->l;
	return tree;
} 

template<class T>
T AVLTree<T>::minimum()
{
	Node<T>* p=minimum(root);
	if(p)
	  return p->key;
	else
	  return (T)NULL;
}

//返回最大值
template<class T>
Node<T>* AVLTree<T>::maximum(Node<T> *tree)
{
	if(!tree) return NULL;
	while(tree->r) tree=tree->r;
	return tree;
} 

template<class T>
T AVLTree<T>::maximum()
{
	Node<T>* p=maximum(root);
	if(p)
	  return p->key;
	else
	  return (T)NULL; 
}
 
//LL旋转 
template<class T>
Node<T>* AVLTree<T>::LL(Node<T> *root)
{
	Node<T>* L=root->l;
	root->l=L->r;
	L->r=root;
	root->h=max(height(root->l),height(root->r))+1;
	L->h=max(height(L->l),root->h)+1;
	return L;
}

//RR旋转
template<class T>
Node<T>* AVLTree<T>::RR(Node<T> *root)
{
	Node<T>* R=root->r;
	root->r=R->l;
	R->l=root;
	root->h=max(height(root->l),height(root->r))+1;
	R->h=max(height(R->r),root->h)+1;
	return R;
} 

//LR旋转
template<class T>
Node<T>* AVLTree<T>::LR(Node<T>* root)
{
	root->l=RR(root->l);
	return LL(root);
} 

//RL旋转
template<class T>
Node<T>* AVLTree<T>::RL(Node<T>* root)
{
	root->r=LL(root->r);
	return RR(root);
} 

//将结点z插入AVL树中 
template<class T>
Node<T>* AVLTree<T>::insert(Node<T>* &tree,T key)
{
	if(!tree)
	{
		tree=new Node<T>(key,NULL,NULL);
		if(!tree)
		{
			cout<<"创建结点失败!"<<endl;
			return NULL;
		}
	}
	
	else if(key<tree->key)//key应该插入tree的左子树 
	{
		tree->l=insert(tree->l,key);
		//插入结点后,若AVL树失去平衡,则进行相应的调整
		if(height(tree->l)-height(tree->r)==2)
		{
			if(key<tree->l->key)
			  tree=LL(tree);
			else
			  tree=LR(tree); 
		} 
	}
	
	else if(key>tree->key)//key应该插入tree的右子树
	{
		tree->r=insert(tree->r,key);
		//插入结点后,若AVL树失去平衡,则进行相应的调整
		if(height(tree->r)-height(tree->l)==2)
		{
			if(key<tree->r->key)
			  tree=RL(tree);
			else
			  tree=RR(tree);
		} 
	}
	
	else
	{
		cout<<"不允添加相同的结点!"<<endl; 
	} 
	tree->h=max(height(tree->l),height(tree->r))+1;
	return tree;//返回根结点 
}

template<class T>
void AVLTree<T>::insert(T key)
{
	insert(root,key);
}

template<class T>
Node<T>* AVLTree<T>::remove(Node<T>* &tree,Node<T> *z)
{
	//根为空或者没有要删除的结点,直接返回NULL
	if(!tree||!z) return NULL;
	if(z->key<tree->key)//待删除结点在tree的左子树中 
	{
		tree->l=remove(tree->l,z);
		//删除结点后,若AVL树失去平衡,则进行相应的调整
		if(height(tree->r)-height(tree->l)==2)
		{
			if(height(tree->r->l)>height(tree->r->r))
			  tree=RL(tree);
			else
			  tree=RR(tree);
		} 
	} 
	
	else if(z->key>tree->key)//待删除结点在tree的右子树中
	{
		tree->r=remove(tree->r,z);
		//删除结点后,若AVL树失去平衡,则进行相应的调整
		if(height(tree->l)-height(tree->r)==2)
		{
			if(height(tree->l->l)>height(tree->l->r))
			  tree=LL(tree);
			else
			  tree=LR(tree);
		} 
		
	}
	
	else//tree对应要删除的结点 
	{
		//tree的左右孩子都非空
		if(tree->l&&tree->r)
		{
			//tree的左子树比右子树高 
			if(height(tree->l)>height(tree->r))
			{
				//找出tree的左子树中的最大结点,将其键值赋给tree,然后删除它
				Node<T>* maxNode=maximum(tree->l);
				tree->key=maxNode->key;
				tree->l=remove(tree->l,maxNode); 
			}
			//tree的右子树的高度大于或等于左子树高度 
			else
			{
				//找出tree的右子树中的最小结点,将其键值赋给tree,然后删除它
				Node<T>* minNode=minimum(tree->r);
				tree->key=minNode->key;
				tree->r=remove(tree->r,minNode); 
			}
		}
		//tree的左右孩子只要有一个为空 
		else
		{
			Node<T>* tmp=tree;
			tree=(tree->l)?tree->l:tree->r;
			delete tmp;
		} 
	} 
	return tree; //返回根结点 
} 

template<class T>
void AVLTree<T>::remove(T key)
{
	Node<T> *z=search(root,key);
	if(z) root=remove(root,z);
} 

//销毁AVL树
template<class T>
void AVLTree<T>::destroy(Node<T>* &tree)
{
	if(tree)
	{
		destroy(tree->l);
		destroy(tree->r);
		delete tree;
	}
} 

template<class T>
void AVLTree<T>::destroy()
{
	destroy(root);
}

template<class T>
void AVLTree<T>::print(Node<T> *tree,T key,int child)
{
	if(tree)
	{
		if(child==0)
		  cout<<tree->key<<" is root"<<endl;
		else
		  cout<<tree->key<<" is "<<key<<"'s "<<(child==1?"left child":"right child")<<endl;
		print(tree->l,tree->key,1);
		print(tree->r,tree->key,-1);
	}
}

template<class T>
void AVLTree<T>::print()
{
	if(root) print(root,root->key,0);
}

猜你喜欢

转载自blog.csdn.net/SongBai1997/article/details/85217129