- UID
- 580
- 精华
- 积分
- 561
- 威望
- 点
- 宅币
- 个
- 贡献
- 次
- 宅之契约
- 份
- 最后登录
- 1970-1-1
- 在线时间
- 小时
|
本帖最后由 0x55AA 于 2014-12-8 17:54 编辑
1 AVL树的定义
AVL树是一种自平衡二叉排序树,它的特点是任何一个节点的左子树高度和右子树的高度差在-1,0,1三者之间。AVL树的任何一个子树都是AVL树。
2 AVL树的实现
AVL树本质是一种二叉排序树,所以二叉排序树的任何性质AVL树都具有,但是AVL树稍微复杂的地方就是AVL树必须满足平衡条件,具体跟BST不同的地方主要体现在插入,删除操作。
插入操作:当插入之后可能会出现不平衡,所以这时候要通过旋转树来实现平衡。旋转有四种类型,左左,左右,右左,右右。其中左左旋转和右右旋转是镜像的,左右旋转和右左旋转是镜像的,所以实质上就是两种类型的旋转。针对左左旋转,只需要旋转一次即可,针对左右旋转,需要执行两次旋转。见下图:
这里采用递归法实现插入和删除操作。使用递归方便的一点是如果函数的参数是引用类型的,当传入一个p->left的时候,我们在当前函数的下层递归的时候,对p进行的赋值操作其实就是对上层递归中的p->left进行的操作,所以这样就不需要传递父指针了。
3 实现代码
AVLTree.h- //AVLTree.h
- #ifndef DDXX_AVLTREE_H
- #define DDXX_AVLTREE_H
- #include <iostream>
- #include <queue>
- using namespace std;
- template<typename Type>
- class AVLTree
- {
- struct Node
- {
- Type e;
- Node* left;
- Node* right;
- int h;
- Node(Type _e):e(_e),left(NULL),right(NULL),h(0){}
- Node(Type _e,Node* _left,Node* _right,int _h):e(e),left(_left),right(_right),h(_h){}
- };
- public:
- AVLTree();
- AVLTree(Type arr[],int nLength);
- /*AVLTree(const AVLTree& right);
- AVLTree& operator=(const AVLTree& right);*/
- ~AVLTree();
- public:
- bool insert(Type e,Node* &p);
- void erase(Type e,Node* &p);
- Node*& find(Type e)const;
- void traverse(Node* p)const;
- void traverseByLevel(Node* p)const;
- int getLength(){return mLength;}
- Node*& getParent(Node* p);
- Node*& getRoot(){return mRoot;} //notice the return type
- bool empty(){return mRoot==NULL;};
- void clear();
- void clears(Node* &p);
- private:
- void rotateLeft(Node* &k2);
- void rotateRight(Node* &k2);
- void rotateLeftDouble(Node* &p);
- void rotateRightDouble(Node* &p);
- int height(Node* p)const{ return p == NULL ? -1 : p->h ;}
- int max(int x,int y){return x>y?x:y;}
- private:
- Node* mRoot;
- int mLength;
- };
- template<typename Type> AVLTree<Type>::AVLTree():mRoot(NULL),mLength(0)
- {
- }
- template<typename Type> AVLTree<Type>::AVLTree(Type arr[],int nLength):mRoot(NULL),mLength(0)
- {
- for(int i=0;i<nLength;i++)
- {
- insert(arr[i],mRoot);
- }
- }
- template<typename Type> AVLTree<Type>::~AVLTree()
- {
- clears(mRoot);
- }
- template<typename Type> bool AVLTree<Type>::insert(Type e,Node* &p)
- {
- if( p== NULL)
- {
- p = new Node(e);
- mLength++;
- }
- else if(e < p->e)
- {
- insert(e,p->left);
- if( height(p->left) - height(p->right) == 2)
- {
- if (e < p->left->e)
- rotateLeft(p);
- else
- rotateLeftDouble(p);
- }
- }
- else if(e > p->e)
- {
- insert(e,p->right);
- if( height(p->left) - height(p->right) == -2)
- {
- if (e > p->right->e)
- rotateRight(p);
- else
- rotateRightDouble(p);
- }
- }
- else // e ia already exist
- {
- //return false;
- }
- p->h = max( height(p->left),height(p->right) )+1;
- return true;
- }
- template<typename Type> void AVLTree<Type>::rotateLeft(Node*& k2)
- {
- Node* k1 = k2->left;
- k2->left = k1->right;
- k1->right = k2;
- k1->h = max( height(k1->left),height(k1->right) ) + 1;
- k2->h = max( height(k2->left),height(k2->right) ) + 1;
- k2 = k1;// join the original node
- }
- template<typename Type> void AVLTree<Type>::rotateRight(Node* &k2)
- {
- Node* k1 = k2->right;
- k2->right = k1->left;
- k1->left = k2;
- k1->h = max( height(k1->left),height(k1->right) ) + 1;
- k2->h = max( height(k2->left),height(k2->right) ) + 1;
- //k1=k2,因为在insert函数中传入的是p->left或者p->right的引用,所以这里能把根结点赋给其父结点的子节点
- k2 = k1;
- }
- template<typename Type> void AVLTree<Type>::rotateLeftDouble(Node*& k3)
- {
- rotateRight(k3->left);
- rotateLeft(k3);
- }
- template<typename Type> void AVLTree<Type>::rotateRightDouble(Node*& k3)
- {
- rotateLeft(k3->right);
- rotateRight(k3);
- }
- template<typename Type> void AVLTree<Type>::traverse(Node* p)const
- {
- if( p == NULL)
- return;
- else
- {
- traverse(p->left);
- cout<<"element:"<<p->e<<endl; //traverse by mid
- traverse(p->right);
- }
- }
- template<typename Type> void AVLTree<Type>::traverseByLevel(Node* root)const
- {
- if(root == NULL)
- {
- cout<<"The tree is empty"<<endl;
- return;
- }
- queue<Node*> que;
- que.push(root);
- while( !que.empty() )
- {
- Node* ptr = que.front();
- que.pop();
- cout<<"element:"<<ptr->e<<" th:"<<height(ptr->left) - height(ptr->right)<<endl;
- if(ptr->left != NULL)
- que.push(ptr->left);
- if(ptr->right != NULL)
- que.push(ptr->right);
- }
- }
- template<typename Type> typename AVLTree<Type>::Node* & AVLTree<Type>::getParent(Node* p)
- {
- if( p == m_root)
- return NULL;
- Node* ptr = m_root;
- Node* ptf = ptr;
- while( ptr != NULL )
- {
- if ( ptr->e == p->e )
- return ptf;
- if ( ptr->e > p->e )
- {
- ptf = ptr;
- ptr = ptr->leftChild;
- }
- else
- {
- ptf = ptr;
- ptr = ptr->rightChild;
- }
- }
- }
- template<typename Type> typename AVLTree<Type>::Node*& AVLTree<Type>::find(Type e)const
- {
- Node* ptr = m_root;
-
- while(ptr != NULL)
- {
- if ( ptr->e == e )
- return ptr;
- if ( ptr->e > e )
- ptr = ptr->leftChild;
- else
- ptr = ptr->rightChild;
- }
- //if ( ptr == NULL )
- return NULL;
- }
- template<typename Type> void AVLTree<Type>::clears(Node*& p)
- {
- if( p == NULL )
- return;
- else
- {
- clears(p->left);
- clears(p->right);
- delete p;
- p = NULL;
- mLength--;
- }
- }
- template<typename Type> void AVLTree<Type>::clear()
- {
- clears(mRoot);
- }
- template<typename Type> void AVLTree<Type>::erase(Type e,Node* &p)
- {
- if( p == NULL)
- return;
- if( e > p->e)
- {
- erase(e,p->right);
- if( height(p->left) - height(p->right) == 2)
- {
- if( height(p->left->left) > height(p->left->right) )
- rotateLeft(p);
- else
- rotateLeftDouble(p);
- }
- }
- else if( e < p->e)
- {
- erase(e,p->left);
- if( height(p->left) - height(p->right) == -2)
- {
- if( height(p->right->right) > height(p->right->left) )
- rotateRight(p);
- else
- rotateRightDouble(p);
- }
- }
- else if ( e == p->e && p->left!= NULL && p->right!= NULL)
- {
- Node* pmax = p->left;
- while( pmax->right != NULL)
- {
- pmax = pmax->right;
- }
- p->e = pmax->e;
- erase(p->e,p->left);
- }
- else //最终的删除会在这里执行
- {
- Node* pNew = p->left==NULL ? p->right : p->left;
- delete p;
- p = pNew;
- mLength--;
- }
- if ( p!=NULL)
- p->h = max( height(p->left),height(p->right)) + 1;
- }
- #endif
复制代码 main.cpp- //main.cpp
- #include <iostream>
- #include "AVLTree.h"
- using namespace std;
- void main()
- {
- int Arr[9] = {6,2,8,4,10,0,12,16,14};
- AVLTree<int> Tr(Arr,9);
- Tr.traverse(Tr.getRoot());
- Tr.traverseByLevel(Tr.getRoot());
- Tr.erase(14,Tr.getRoot());
- Tr.traverse(Tr.getRoot());
- Tr.traverseByLevel(Tr.getRoot());
- cout<<"Tree's length is:"<<Tr.getLength()<<endl;
- Tr.clear();
- cout<<"Tree's length is:"<<Tr.getLength()<<endl;
- }
复制代码 |
|