AVL树的平衡过程

平衡二叉树(balanced binary tree)又称为AVL树。它或者是一颗空树,或者是具有下列性质的二叉树:它的左子树和右子树都是平衡二叉树,且左右子树的深度之差的绝对值不超过1。若将二叉树上节点 的平衡因子BF(balance factor)定义为该节点的左子树深度减去右子树深度。则BF={-1,1,0}

平衡二叉树是在节点的插入过程中动态生成的,这种性质的查找树又称为动态查找树。AVL树与一般的查找树不同的是当插入一个节点导致二叉树失衡时(BF!={1,-1,0}),需要对树进行平衡处理。

AVL树的平衡根据使树失衡的节点所在的位置分为4种类型:LL型(节点插入位置为左子树根节点的左子树),LR型(左子树根节点的右子树),RR型(右子树根节点右子树),RL型(右子树根节点的左子树)。  调整树使其平衡的方法有两种:左旋,右旋。

对应每一种失衡类型做相应的平衡方法即可使树重新平衡:

LL—–>对根节点左旋

LR—–>先对根节点的左子树根左旋,再对根节点右旋

RR—->对根节点右旋

RL—->先对根节点的右子树根右旋,再对根节点左旋

理解AVL树平衡算法的关键是了解左旋右旋操作以及四种失衡类型各自对应的情况,可通过画图来理解。具体图解可参考数据结构P235

以下是我实现的AVL树的部分操作:

#include "stdafx.h"
#include <iostream>
using namespace std ;

#include <vector>

struct AVLtreeNode
{
	int val;
	int bf ;  //  balance factor
	struct AVLtreeNode *left,*right;
	AVLtreeNode():val(0),bf(0),left(NULL),right(NULL){}
};

class AVLTree
{
private:
	AVLtreeNode *Root;

public:
	AVLTree(vector<int> &nodes);
	void R_Rotate(AVLtreeNode *&);
	void L_Rotate(AVLtreeNode *&);

	bool InsertNode(AVLtreeNode *&root,int val,bool &taller);
	void InOrderTrav(AVLtreeNode *root);
	void LeftBalance(AVLtreeNode *&node);
	void RightBalance(AVLtreeNode *&node);
};

AVLTree::AVLTree(vector<int> &nodes)
{
	Root=NULL;
	bool taller=false;
	for(vector<int>::iterator iter=nodes.begin();iter!=nodes.end();++iter)
	{
		InsertNode(Root,*iter,taller);
	}
	InOrderTrav(Root);
	cout<<endl;
}

bool  AVLTree::InsertNode(AVLtreeNode *&root,int val,bool &taller)
{
	if(!root)
	{
		root=new AVLtreeNode();
		root->val=val;
		taller=true;
	}
	else
	{
		if(root->val==val)
		{
			taller=false;
			return false;
		}
		if(root->val>val)   // insert left 
		{
			if(!InsertNode(root->left,val,taller)) return false;
			if(taller)
			{
				switch(root->bf)
				{
				case 1:
					LeftBalance(root);
					taller=false;
					break;
				case 0:
					root->bf=1;
					taller=true;
					break;
				case -1:
					root->bf=0;
					taller=false;
					break;
				}
			}
		}
		else   //insert right
		{
			if(!InsertNode(root->right,val,taller)) return false;
			if(taller)
			{
				switch(root->bf)
				{
				case -1:
					RightBalance(root);
					taller=false;
					break;
				case 0:
					root->bf=-1;
					taller=true;
					break;
				case 1:
					taller=false;
					root->bf=0;
					break;
				}

			}
		}
	}

	return true;

}

void AVLTree::R_Rotate(AVLtreeNode *&node)
{
//	AVLtreeNode* p=node;
	AVLtreeNode* lc=node->left;
	node->left=lc->right;
	lc->right=node;
	node=lc;
}

void AVLTree::L_Rotate(AVLtreeNode *&node)
{
//	AVLtreeNode *p=node;
	AVLtreeNode *rc=node->right;
	node->right=rc->left;
	rc->left=node;
	node=rc;
}

void AVLTree::LeftBalance(AVLtreeNode *&node)
{
//	AVLtreeNode *p=node;
	AVLtreeNode *lc=node->left;
	switch(lc->bf)
	{
	case 1:   //  LL型   右旋
		node->bf=0;
		lc->bf=0;
		R_Rotate(node);
		break;
	case -1:   //LR型   先对左子树根节点左旋  再对根节点右旋
		AVLtreeNode *rd=lc->right;
		switch(rd->bf)
		{
		case 1:
			node->bf=-1;
			lc->bf=0;
			break;
		case 0:     //rd.bf==0 的情况是加入的节点为rd本身!!
			node->bf=0;
			lc->bf=0;
			break;
		case -1:
			node->bf=0;
			lc->bf=1;
			break;
		}
		rd->bf=0;
		L_Rotate(node->left);
		R_Rotate(node);
	}
}

void AVLTree::RightBalance(AVLtreeNode *&node)
{
//	AVLtreeNode* p=node;
	AVLtreeNode* rc=node->right;
	switch(rc->bf)
	{
	case -1:   //RR型   左旋
		node->bf=0;
		rc->bf=0;
		L_Rotate(node);
		break;
	case 1:    //
		AVLtreeNode* ld=rc->left;
		switch(ld->bf)
		{
		case 1:
			node->bf=0;
			rc->bf=-1;
			break;
		case 0:
			node->bf=0;
			rc->bf=0;
			break;
		case -1:
			node->bf=1;
			rc->bf=0;
			break;
		}
		ld->bf=0;
		R_Rotate(node->right);
		L_Rotate(node);
	}
}


void AVLTree::InOrderTrav(AVLtreeNode* root)
{
	if(!root)
		return ;
	InOrderTrav(root->left);
	cout<<root->val<<" ";
	InOrderTrav(root->right);
}


int main()
{
	int arr[]={13,24,37,90,53};
	vector<int> nodes(arr,arr+5);
	AVLTree tree(nodes);

	return 0;
}
    原文作者:AVL树
    原文地址: https://blog.csdn.net/zhxuan30/article/details/41440499
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞