AVL 平衡二叉树的实现

平衡二叉树的定义:
平衡二叉树或者是一棵空树,或者是具有以下性质的二叉排序树:
平衡二叉树的左子树和右子树的深度之差小于等于1,且左子树和右子树也是平衡二叉树。

二叉排序树的定义:
二叉排序树或者是一棵空树,或者是具有以下性质的二叉树:
1、若任意结点的左子树不空,则左子树上所有结点的值均小于它的根结点的值;
2、任意结点的右子树不空,则右子树上所有结点的值均大于它的根结点的值;
3、任意结点的左、右子树也分别为二叉排序树。
4、没有键值相等的结点。

向一棵平衡二叉树中插入/删除结点可能使平衡二叉树失去平衡,通过使插入点/删除点最近的祖先结点恢复平衡,从而使上一层祖先结点恢复平衡。
因此,为了使平衡二叉树保持平衡,需要从离插入点/删除点最近的结点开始调整。
造成平衡二叉树失衡的类型以及调整方法可以归纳为以下四种情况:









总结如下:
1、针对LL型,需要进行一次右旋操作
2、针对LR型,需要先进行一次左旋操作,然后进行一次右旋操作
3、针对RL型,需要先进行一次右旋操作,然后进行一次左旋操作
4、针对RR型,需要进行一次左旋操作

相关数据结构与函数代码如下:
typedef int KEY_TYPE;
typedef struct AVL{
	KEY_TYPE key;
	int height;
	struct AVL* lchild;
	struct AVL* rchild;
}AVL;

AVL* New_Node(KEY_TYPE key, AVL* lchild, AVL* rchild, int height = 0);
inline int getHeight(AVL* node);
AVL* Left_Rotate(AVL* k2);
AVL* Right_Rotate(AVL* k2)
AVL* RR_Rotate(AVL* k2);
AVL* LL_Rotate(AVL* k2);
AVL* LR_Rotate(AVL* k3);
AVL* RL_Rotate(AVL* k3);
AVL* Insert(AVL* root, KEY_TYPE key);
AVL* Delete(AVL* root, KEY_TYPE key);
AVL* New_Node(KEY_TYPE key, AVL* lchild, AVL* rchild, int height)
{
	AVL* p_avl = new AVL;
	p_avl->key = key;
	p_avl->lchild = lchild;
	p_avl->rchild = rchild;
	p_avl->height = height;
	return p_avl;
}

inline int getHeight(AVL* node)
{
	return (node==NULL)? -1:node->height;
}

inline int max(int a, int b)
{
	return a>b?a:b;
}

/*  左旋操作:

        k2                       k1
       /  \                     /  \
      X    k1         ==>      k2   Z
          /  \                /  \
         Y    Z              X    Y
 */
AVL* Left_Rotate(AVL* k2)
{
	AVL* k1 = k2->rchild;
	k2->rchild = k1->lchild;
	k1->lchild = k2;
	k2->height = max(getHeight(k2->lchild), getHeight(k2->rchild)) + 1;
	k1->height = max(getHeight(k1->rchild), k2->height) + 1;
	return k1;
}

/*  右旋操作:

        k2                   k1
       /  \                 /  \
      k1   Z     ==>       X   k2
     / \                      /  \
    X   Y                    Y    Z
*/
AVL* Right_Rotate(AVL* k2)
{
	AVL* k1 = k2->lchild;
	k2->lchild = k1->rchild;
	k1->rchild = k2;
	k2->height = max(getHeight(k2->lchild), getHeight(k2->rchild)) + 1;
	k1->height = max(getHeight(k1->lchild), k2->height) + 1;
	return k1;
}
/* LL(针对失衡结点调用右旋操作):

        k2                   k1
       /  \                 /  \
      k1   Z     ==>       X   k2
     / \                      /  \
    X   Y                    Y    Z
*/
AVL* LL_Rotate(AVL* k2)
{
       return Right_Rotate(k2);
}

/* RR(针对失衡结点调用左旋操作):

        k2                       k1
       /  \                     /  \
      X    k1         ==>      k2   Z
          /  \                /  \
         Y    Z              X    Y
 */
AVL* RR_Rotate(AVL* k2)
{
       return Left_Rotate(k2);
}

/* LR(针对失衡结点的左孩子调用左旋操作,针对失衡结点调用右旋操作):

      k3                         k3                       k2
     /  \                       /  \                     /  \
    k1   D                     k2   D                   k1   k3
   /  \         ==>           /  \        ==>          / \   / \
  A    k2                    k1   C                   A  B  C   D
      /  \                  /  \
     B    C                A    B

*/
AVL* LR_Rotate(AVL* k3)
{
	k3->lchild = Left_Rotate(k3->lchild);
	return Right_Rotate(k3);
}


/* RL(针对失衡结点的右孩子调用右旋操作,针对失衡结点调用左旋操作):

       k3                         k3                          k2
      /  \                       /  \                        /  \
     A    k1                    A    k2                     k3   k1 
         /  \       ==>             /  \         ==>       /  \  / \
        k2   B                     C    k1                A   C D   B
       /  \                            /  \
      C    D                          D    B 

 */
AVL* RL_Rotate(AVL* k3)
{
	k3->rchild = Right_Rotate(k3->rchild);
	return Left_Rotate(k3);
}

AVL* Insert(AVL* root, KEY_TYPE key)
{
	if(root == NULL)
		return (root = New_Node(key, NULL, NULL));
	else 
        {
            if(key == root->key)
                    return root;
            else if(key < root->key)
		    root->lchild = Insert(root->lchild, key);
	    else 
		    root->rchild = Insert(root->rchild, key);
        }

	root->height = max(getHeight(root->lchild), getHeight(root->rchild)) + 1;
	if(getHeight(root->lchild) - getHeight(root->rchild) == 2)
	{
		if(key < root->lchild->key)
			root = LL_Rotate(root);
		else
			root = LR_Rotate(root);
	}
	else if(getHeight(root->rchild) - getHeight(root->lchild) == 2)
	{
		if(key < root->rchild->key)
			root = RL_Rotate(root);
		else
			root = RR_Rotate(root);
	}
	return root;
}

AVL* Delete(AVL* root, KEY_TYPE key)
{
	if(!root)
		return NULL;
	if(key == root->key)
	{
		if(root->rchild == NULL)//如果右子树为空,那么左子树只可能为空或者左子树只含有一个根结点
		{
			AVL* temp = root;
			root = root->lchild;
			delete(temp);
			return root;
		}
		else
		{
			AVL* temp = root->rchild;
			while(temp->lchild)
				temp = temp->lchild;//找到root结点的后继结点
			root->key = temp->key;//将后继结点的值赋给root
			root->rchild = Delete(root->rchild, temp->key);//将后继结点删除掉
		}
	}
	else if(key < root->key)
		root->lchild = Delete(root->lchild, key);
	else
		root->rchild = Delete(root->rchild, key);

	root->height = max(getHeight(root->lchild), getHeight(root->rchild)) + 1;
	if(getHeight(root->rchild) - getHeight(root->lchild) == 2)
	{
		if(getHeight(root->rchild->rchild) >= getHeight(root->rchild->lchild))
			root = RR_Rotate(root);
		else
			root = RL_Rotate(root);
	}
	else if(getHeight(root->lchild) - getHeight(root->rchild) == 2)
	{
		if(getHeight(root->lchild->lchild) >= getHeight(root->lchild->rchild))
			root = LL_Rotate(root);
		else
			root = LR_Rotate(root);
	}
	return root;
}




评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值