平衡二叉树(AVL树)

平衡二叉树也是一种查找树,所以插入的数据也要满足左孩子比自己小,右孩子比自己大。并且要保持左右孩子的高度差不超过1.

插入分为4种情况:LL插入,RR插入,LR插入,RL插入。调整的方法4种与之分别对应:LL旋转,RR旋转,LR旋转,RL旋转。

LL插入,就是在结点的左子树的左孩子上面插入了新的数据,导致平衡性被破坏。所以进行LL旋转,以下同理

RR插入:

LR

第一次旋转是围绕k1进行RR旋转,第二次是围绕k3进行LL旋转。

RL

测试一组数,将他们插入树中,插入过程都调整成AVL树:

#include<iostream>
#include<algorithm>
#include<vector>
#include<queue>

using namespace std;

typedef struct AVLTreeNode
{
	int val;//值
	int height;//高度
	AVLTreeNode* left;
	AVLTreeNode* right;
}*AVLTree;

int getHeight(AVLTree node)
{
	if(node == nullptr)
		return 0;
	return node->height;
}

AVLTree LeftLeftRotation(AVLTree A)//左单旋,更新A,B的高度,返回新的根结点B
{//A必须有一个左子节点B
	AVLTree B = A->left;
	A->left = B->right;
	B->right = A;
	A->height = max(getHeight(A->left), getHeight(A->right)) + 1;
	B->height = max(getHeight(B->left), A->height) + 1;

	return B;
}

AVLTree RightRightRotation(AVLTree A)//右单旋,更新A,B的高度,返回新的根结点B
{//A必须有一个右子节点B
	AVLTree B = A->right;
	A->right = B->left;
	B->left = A;
	A->height = max(getHeight(A->left), getHeight(A->right)) + 1;
	B->height = max(getHeight(B->right), A->height) + 1;

	return B;
}

AVLTree LeftRightRotation(AVLTree A)//LR旋转
{//A必须有一个左子节点B,B有一个右子结点C

	A->left = RightRightRotation(A->left);//将B,C做右单旋,C被返回

	return LeftLeftRotation(A);//将A,C做左单旋,C被返回
}

AVLTree RightLeftRotation(AVLTree A)//RL旋转
{//A必须有一个右子节点B,B有一个左子结点C

	A->right = LeftLeftRotation(A->right);//将B,C做左单旋,C被返回

	return RightRightRotation(A);//将A,C做右单旋,C被返回
}

//将X插入AVL树T,返回调整后的AVL树
AVLTree insertion(int X, AVLTree T)
{
	if(!T)//如果插入空树,新建包含一个结点的树
	{
		T = (AVLTree)malloc(sizeof(AVLTreeNode));
		T->val = X;
		T->height = 0;
		T->left = T->right = nullptr;
	}
	else if(X < T->val)//插入T的左子树
	{
		T->left = insertion(X, T->left);
		if(getHeight(T->left) - getHeight(T->right) == 2)
		{
			if(X < T->left->val)//左单旋
				T = LeftLeftRotation(T);
			else//左右旋转
				T = LeftRightRotation(T);
		}
	}
	else if(X > T->val)
	{
		T->right = insertion(X, T->right);
		if(getHeight(T->left) - getHeight(T->right) == -2)
		{
			if(X > T->right->val)//右单旋
				T = RightRightRotation(T);
			else//右左旋转
				T = RightLeftRotation(T);
		}
	}

	//更新树高
	T->height = max(getHeight(T->left), getHeight(T->right)) + 1;

	return T;
}

//层序遍历
vector<vector<int> > print(AVLTree root)
{
	vector<vector<int> > res;
	if(root == nullptr)
		return res;

	queue<AVLTree> q;
	q.push(root);
	while(!q.empty())
	{
		vector<int> tmp;
		const int len = q.size();
		for(int i = 0; i < len; ++i)
		{
			AVLTree node = q.front();
			int data = q.front()->val;
			q.pop();

			if(node->left)
			{
				q.push(node->left);
			}
			if(node->right)
			{
				q.push(node->right);
			}
			tmp.push_back(data);
		}
		res.push_back(tmp);
	}
	return res;
}

int main()
{
	vector<int>test = { 3, 2, 1, 4, 5, 6, 7, 16, 15, 14, 13, 12, 11, 10, 8, 9 };

	AVLTree root = nullptr;
	for(int i = 0; i < test.size(); ++i)
	{
		root = insertion(test[i], root);
	}

	vector<vector<int> > order = print(root);
	for(int i = 0; i < order.size(); ++i)
	{
		for(int j = 0; j < order[i].size(); ++j)
			cout << order[i][j] << " ";
		cout << endl;
	}

	return 0;
}

猜你喜欢

转载自blog.csdn.net/qq_22080999/article/details/81100522