数据结构与算法问题 AVL二叉平衡树

AVL树是带有平衡条件的二叉查找树。这个平衡条件必须保持,而且它必须保证树的深度是O(logN)。



一棵AVL树是其每个节点的左子树和右子树的高度最多差1的二叉查找树。(空树的高度定义为-1)。


在插入以后,只有那些从插入点到根节点的路径上的节点的平衡可能被改变,因为只有这些节点的子树可能发生变化。当我们沿着这条路径上行到根并更新平衡信息时,我们可以找到一个节点,它的新平衡破坏了AVL条件。我们将指出如何在第一个这样的节点(即最深的节点)重新平衡这棵树,并证明,这一重新平衡保证整个树满足AVL特性。



让我们把必须重新平衡的这个节点叫做a。由于任意节点最多有两个儿子,因此高度不平衡时,a点的两棵子树的高度差2。容易看出,这种不平衡可能出现在下面四种情况中:

1.对a的左儿子的左子树进行一次插入

2.对a的左儿子的右子树进行一次插入

3.对a的右儿子的左子树进行一次插入

4.对a的右儿子的右子树进行一次插入




第一种情况是插入发生在“外边"的情况(即左—左的情况或右—右的情况),该情况通过对树的一次单旋转而完成调整。第二种情况是插入发生在”内部“的情形(即左—右的情况或右—左的情况),该情况通过稍微复杂些的双旋转来处理。

AVL树本质上还是一棵二叉搜索树,它的特点是:



  1. 本身首先是一棵二叉搜索树。

  2. 带有平衡条件:每个结点的左右子树的高度之差的绝对值(平衡因子)最多为1


#include <iostream>
using namespace std;
const int LH = 1;
const int EH = 0;
const int RH = -1;
bool TRUE = 1;
bool FALSE = 0;

typedef struct BSTNode
{
	int key;
	int bf;
	BSTNode *lchild, *rchild;
}BSTNode;

//中序遍历
void inordertree(BSTNode * &root)
{
	if (root)
	{
		inordertree(root->lchild);
		cout << root->key<<",";
		inordertree(root->rchild);
	}
}

//前序遍历
void preordertree(BSTNode * &root)
{
	if (root)
	{
		cout << root->key<<",";
		preordertree(root->lchild);
		preordertree(root->rchild);
	}
}
//右旋
void R_Rotate(BSTNode * &p)
{
	BSTNode *lc = p->lchild;
	p->lchild = lc->rchild;
	lc->rchild = p;
	p = lc;
}

//左旋
void L_Rotate(BSTNode *& p)
{
	BSTNode *rc = p->rchild;
	p->rchild = rc->lchild;
	rc->lchild = p;
	p = rc;
}

void LeftBalance(BSTNode * &T)
{
	BSTNode *lc = T->lchild;
	switch (lc->bf)
	{
	case LH:
		T->bf = lc->bf = EH;
		R_Rotate(T);
		break;
	case RH:
		BSTNode *rd = lc->rchild;
		switch (rd->bf)
		{
		case LH:
			T->bf = RH;
			lc->bf = EH;
			break;
		case EH:
			T->bf = lc->bf = EH;
			lc->bf = LH;
			break;
		}
		rd->bf = EH;
		L_Rotate(T->lchild);//先左旋
		R_Rotate(T);
		break;
	}
}

void RightBalance(BSTNode *& T)
{
	BSTNode *rc = T->rchild;
	switch (rc->bf)
	{
	case RH:
		T->bf = rc->bf = EH;
		L_Rotate(T);
		break;
	case LH:
		BSTNode *ld = rc->lchild;
		switch (ld->bf)
		{
		case RH:
			T->bf = LH;
			rc->bf = EH;
			break;
		case EH:
			T->bf = rc->bf = EH;
			break;
		case LH:
			T->bf = EH;
			rc->bf = RH;
			break;
		}
		ld->bf = EH;
		R_Rotate(T->rchild);
		L_Rotate(T);
		break;

	}
}

int insertAVL(BSTNode *& t, int e, bool &taller)
{
	if (!t)
	{
		t = new BSTNode;
		t->key = e;
		t->lchild = t->rchild = NULL;
		t->bf = EH;
		taller = TRUE;

	}
	else
	{
		if (e == t->key)
		{
			taller = FALSE;
			return 0;
		}
		if (e < t->key)
		{
			if (!insertAVL(t->lchild, e,taller))
				return 0;
			if (taller)
			{
				switch (t->bf)
				{
				case LH:
					LeftBalance(t);
					taller = FALSE;
					break;
				case EH:
					t->bf = LH;
					taller = TRUE;
					break;
				case RH:
					t->bf = EH;
					taller = FALSE;
					break;

				}
			}
		}
		else
		{
			if (!insertAVL(t->rchild, e, taller))
				return 0;
			if (taller)
			{
				switch (t->bf)
				{
				case RH:
					RightBalance(t);
					taller = FALSE;
					break;
				case EH:
					t->bf = RH;
					taller = TRUE;
					break;
				case LH:
					t->bf = EH;
					taller = FALSE;
					break;
				}
			}
		}
	}
	return 1;
}

BSTNode *search(BSTNode *t, int key)
{
	BSTNode *p = t;
	while (p)
	{
		if (p->key == key)
			return p;
		else if (p->key < key)
			p = p->rchild;
		else
			p = p->lchild;
	}
	return p;
}

int main()
{
	BSTNode *root = NULL;
	BSTNode *r;
	bool taller = FALSE;
	int array[] = { 13, 24, 37, 90, 53 };
	for (int i = 0; i < 5; i++)
		insertAVL(root, array[i], taller);
	cout << "inorder traverse..." << endl;
	inordertree(root);
	cout << endl;
	cout << "preorder traverse..." << endl;
	preordertree(root);
	cout << endl;
	cout << "search key..." << endl;
	r = search(root, 37);
	if (r)
	{
		cout << r->key << endl;
	}
	else
	{
		cout << "not find" << endl;
	}
	system("pause");
	return 0;
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值