设为首页 加入收藏

TOP

C++模板实现的AVL树(一)
2015-02-02 14:32:58 来源: 作者: 【 】 浏览:21
Tags:模板 实现 AVL

1 AVL树的定义


AVL树是一种自平衡二叉排序树,它的特点是任何一个节点的左子树高度和右子树的高度差在-1,0,1三者之间。AVL树的任何一个子树都是AVL树。


2 AVL树的实现


AVL树本质是一种二叉排序树,所以二叉排序树的任何性质AVL树都具有,但是AVL树稍微复杂的地方就是AVL树必须满足平衡条件,具体跟BST不同的地方主要体现在插入,删除操作。


插入操作:当插入之后可能会出现不平衡,所以这时候要通过旋转树来实现平衡。旋转有四种类型,左左,左右,右左,右右。其中左左旋转和右右旋转是镜像的,左右旋转和右左旋转是镜像的,所以实质上就是两种类型的旋转。针对左左旋转,只需要旋转一次即可,针对左右旋转,需要执行两次旋转。见下图:



这里采用递归法实现插入和删除操作。使用递归方便的一点是如果函数的参数是引用类型的,当传入一个p->left的时候,我们在当前函数的下层递归的时候,对p进行的赋值操作其实就是对上层递归中的p->left进行的操作,所以这样就不需要传递父指针了。


3 实现代码


//AVLTree.h


#ifndef DDXX_AVLTREE_H
#define DDXX_AVLTREE_H
#include
#include
using namespace std;
template
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 AVLTree::AVLTree():mRoot(NULL),mLength(0)
{
}


template AVLTree::AVLTree(Type arr[],int nLength):mRoot(NULL),mLength(0)
{
?for(int i=0;i?{
? insert(arr[i],mRoot);
?}
}


template AVLTree::~AVLTree()
{
?clears(mRoot);
}
template bool AVLTree::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 void AVLTree::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 void AVLTree::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 void AVLTree::rotateLeftDouble(Node*& k3)
{
?rotateRight(k3->left);
?rotateLeft(k3);
}
template void AVLTree::rotateRightDouble(Node*& k3)
{
?rotateLeft(k3->right);
?rotateRight(k3);
}


template void AVLTree::traverse(Node* p)const
{
?if( p == NULL)
? return;
?else
?{
? traverse(p->left);
? cout<<"element:"<e<? traverse(p->right);?
?}
}


template void AVLTree::traverseByLevel(Node* root)const
{
?if(root == NULL)
?{
? cout<<"The tree is empty"<? return;
?}
?queue que;
?que.push(

首页 上一页 1 2 下一页 尾页 1/2/2
】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
分享到: 
上一篇C++虚函数访问权限的改变 下一篇C++之 typedef void *HANDLE

评论

帐  号: 密码: (新用户注册)
验 证 码:
表  情:
内  容: