数据结构之AVL树

     AVL树是一种自平衡的二叉树,在AVL树里任何节点的两个子树的高度之差不能超过1,所以他是一种高度平衡的二叉查找树,他能保证查找,插入,删除在最坏的情况下都是

O(log(n))的,不过插入和删除都需要通过一次或多次的单旋转或双旋转来调节平衡!

   以下是调节平衡的例子:


接下来是我的C++代码实现:

#include<iostream>
#include<cstdio>
using namespace std;
#include<ctime>
template<class obj_s>
class avltree{
	struct avlnode
	{
		obj_s ele;
		avlnode *left;
		avlnode *right;
		int height;
		avlnode(const obj_s &tele,avlnode *lt=NULL,avlnode *rt=NULL,int h=0)
			:ele(tele),left(lt),right(rt),height(h){}
	};
	int height (avlnode *t)const
	{
		return t==NULL?-1:t->height;
	}
	avlnode *root;
	void clear(avlnode * &t)
	{
		if(t==NULL)
			return;
		clear(t->left);
		clear(t->right);
		delete t;
	}
	avlnode * clone(avlnode * t)
	{

		if(t!=NULL)
		return new avlnode(t->ele,clone(t->left),clone(t->right),t->height);
		return NULL;
	}

	void insert(const obj_s &x,avlnode *&t)
	{


		if(t==NULL)
			t=new avlnode(x);
		else if(x<t->ele)
		{  insert(x,t->left);
			if(height(t->left)-height(t->right)==2)
			{	if(x<t->left->ele)
					rotatewithleftchild(t);
				else
					doublewithleftchild(t);
			}
		}
		else if(t->ele<x)
		{	insert(x,t->right);
			if(height(t->left)-height(t->right)==-2)
			{if(t->right->ele<x)
					rotatewithrightchild(t);
				else
					doublewithrightchild(t);
			}
		}

		else
			;
		t->height=height(t->left)-height(t->right)>0?height(t->left)+1:height(t->right)+1;
	}
	 void remove(const obj_s &x,avlnode * &t)
		{
		 if(t==NULL)
	              	return ;
              else if(x<t->ele)
			  {
	            remove(x,t->left);
			   if(height(t->right)-height(t->left)==2)
			   {
				   if(height(t->right->left)-height(t->right->right)<=0) //如果右左比右右小,那实行右单旋,否者右双旋,以下类似,
					                                                     //思想就是删除与插入基本是相反的过程
					rotatewithrightchild(t);
				   else
					doublewithrightchild(t);
			   }
			  }
              else if(x>t->ele)
			  {
	          	remove(x,t->right);
		    	if(height(t->left)-height(t->right)==2)
				{
					if(height(t->left->left)-height(t->left->right)>=0)
					rotatewithleftchild(t);
			    	else
					doublewithleftchild(t);
				}
			  }
	        else if(t->left !=NULL && t->right !=NULL)
			{
	        	t->ele=findMin(t->right)->ele;
	        	remove(t->ele,t->right);
			if(height(t->left)-height(t->right)==2)
			{
				if(height(t->left->left)-height(t->left->right)>=0)
					rotatewithleftchild(t);
				else
					doublewithleftchild(t);
			}
			}
	        else
			{
	            avlnode *oldnode=t;
	        	t=(t->left!=NULL)?t->left:t->right;
		        delete oldnode;

			}
	if(t!=NULL)


	t->height=height(t->left)-height(t->right)>0?height(t->left)+1:height(t->right)+1;



		}
	void rotatewithleftchild(avlnode *&t2)
	{
		avlnode *t1=t2->left;
		t2->left=t1->right;
		t1->right=t2;
       	t2->height=height(t2->left)-height(t2->right)>0?height(t2->left)+1:height(t2->right)+1;
		t1->height=height(t1->left)-t2->height>0?height(t1->left)+1:t2->height+1;
		t2=t1;
	}
	void rotatewithrightchild(avlnode *&t1)
	{
		avlnode *t2=t1->right;
		t1->right=t2->left;
		t2->left=t1;
       	t1->height=height(t1->left)-height(t1->right)>0?height(t1->left)+1:height(t1->right)+1;
		t2->height=height(t2->right)-t1->height>0?height(t2->right)+1:t1->height+1;
		t1=t2;
	}
	void doublewithleftchild(avlnode *&t)
	{
		rotatewithrightchild(t->left);
        rotatewithleftchild(t);
	}
	void doublewithrightchild(avlnode *&t)
	{
		rotatewithleftchild(t->right);
        rotatewithrightchild(t);
	}
	void display(avlnode *t,int i=0)
	{
		if(t!=NULL)
		{

		 display(t->right,i+1);
		 for(int j=0;j<i;j++)
         cout<<"  ";
         cout<<t->ele<<endl;
         display(t->left,i+1);
		}
	}
	avlnode *findMin(avlnode *t)const
		{
	        if(t==NULL)
	     	  return NULL;
	        if(t->left==NULL)
	           return t;
	         return findMin(t->left);
		}
	avlnode *findMax(avlnode *t)const
		{
	        if(t==NULL)
	     	  return NULL;
	        if(t->right==NULL)
	           return t;
	           return findMax(t->right);
		}

	 bool contains(const obj_s &x,avlnode *t)const//查找;
		{
            	if(t==NULL)
	                 	return false;
             	else if(x<t->ele)
		                return contains(x,t->left);
	            else if(x>t->ele)
	                   	return contains(x,t->right);
                 else
		          return true;
		}


public:
	avltree(){root=NULL;}
	avltree(const avltree &rhs)
	{    root=NULL;
		*this=rhs;

	}
	~avltree(){clear();}
	void clear()
	{
		clear(root);
		root=NULL;
	}
	avltree & operator=(const avltree &rhs)
	{	if(this!=&rhs)
		{   clear();
			root=clone(rhs.root);
		}
		return *this;
	}
	void insert (const obj_s &x)
	{
		insert(x,root);
	}


    int height()
	{
		return height(root);
	}
    void display()
	{
		display(root);
	}
	const obj_s & findMin()const
	    {
			 return findMin(root)->ele;
		}
    const obj_s & findMax()const
		{
			  return findMax(root)->ele;
		};
    void remove(const obj_s &x)
		{
			remove(x,root);
		}
    bool contains(const obj_s &x)
	{
		return contains(x,root);
	}


};
int main(){
    freopen("out.txt","w",stdout);
	avltree<int> T;
	clock_t start,finish;
	start=clock();
	for(int i=1;i<=100;i++)
		T.insert(i);
      T.display();
	finish=clock();
	cout<<double(finish-start)/CLOCKS_PER_SEC<<"s"<<endl;
    fclose(stdout);

	return 0;
}

然后是out.txt的结果:

            100
          99
        98
          97
      96
            95
          94
            93
        92
            91
          90
            89
    88
          87
        86
          85
      84
          83
        82
          81
  80
          79
        78
          77
      76
          75
        74
          73
    72
          71
        70
          69
      68
          67
        66
          65
64
            63
          62
            61
        60
            59
          58
            57
      56
            55
          54
            53
        52
            51
          50
            49
    48
            47
          46
            45
        44
            43
          42
            41
      40
            39
          38
            37
        36
            35
          34
            33
  32
            31
          30
            29
        28
            27
          26
            25
      24
            23
          22
            21
        20
            19
          18
            17
    16
            15
          14
            13
        12
            11
          10
            9
      8
            7
          6
            5
        4
            3
          2
            1

0.000657s

可以看到,这棵树是非常平衡的,尽管我是按照顺序插入也是如此,这是普通的二叉查找树所无法实现的。

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值