AVL树相关的一些操作

#include<cstdio>
#include<queue>
#include<algorithm>
using namespace std;
struct node
{
	int v, height;//v为结点权值,height为当前子树高度
	node *lchild, *rchild;
};
//生成一个新结点,v为结点权值
node* newNode(int v)
{
	node* Node = new node;//申请一个node型变量的地址空间
	Node->v = v;//结点权值为v
	Node->height = 1;//结点高度初始为1
	Node->lchild = Node->rchild = NULL;//初始状态下没有左右孩子
	return Node;//返回新建结点的地址
}
//获取以root为根结点的子树的当前height
int getHeight(node*root)
{
	if (root == NULL) return 0;
	return root->height;
}
//计算结点root的平衡因子
int getBalanceFactor(node* root)
{
	//左子树高度减右子树高度
	return getHeight(root->lchild) - getHeight(root->rchild);
}
//更新结点root的height
void updateHeight(node* root)
{
	//max(左孩子的height,右孩子的height) + 1
	root->height = max(getHeight(root->lchild), getHeight(root->rchild)) + 1;
}
void search(node *root, int x)
{
	if (root == NULL)
	{
		//空树,查找失败
		printf("search failed\n");
	}
	if (x == root->v)
	{//查找成功,访问之
		printf("%d\n", root->v);
	}
	else if (x < root->v)
	{
		//如果x比根结点的数据域小,说明x在左子树
		search(root->lchild, x);
	}
	else
	{
		//如果x比根结点的数据域大,说明x在右子树
		search(root->rchild, x);//往右子树搜索x
	}
}
//左旋(Left Rotation)
void L(node* &root)
{
	node* temp = root->rchild;//root指向结点A,temp指向结点B
	root->rchild = temp->lchild;//步骤1
	temp->lchild = root;//步骤2
	updateHeight(root);//更新结点A的高度
	updateHeight(temp);//更新结点B的高度
	root = temp;//步骤3
}
//右旋(Right Rotation)
void R(node* &root)
{
	node* temp = root->lchild;//root指向结点B,temp指向结点A
	root->lchild = temp->rchild;//步骤1
	temp->rchild = root;//步骤2
	updateHeight(root);//更新结点B的高度
	updateHeight(temp);//更新结点A的高度
	root = temp;//步骤3
}
//插入权值为v的结点
void insert(node* &root, int v)
{
	if (root == NULL)
	{
		//到达空结点
		root = newNode(v);
		return;
	}
	if (v < root->v)
	{
		//v比根结点的权值小
		insert(root->lchild, v);//往左子树插入,每次插完后都要记得更新树高和旋转调整使得平衡因子合法
		updateHeight(root);//更新树高
		if (getBalanceFactor(root) == 2)//说明左边太高了
		{
			if (getBalanceFactor(root->lchild) == 1)//说明子树的左边还是高,那么就是LL型
			{
				//LL型
				R(root);
			}
			else if (getBalanceFactor(root->lchild) == -1)//说明子树的右边高,那么就是LR型
			{
				//LR型
				L(root->lchild);//先转化成LL型,参数是啥就旋转啥,RL型同理
				R(root);
			}
		}
	}
	else
	{
		//v比根结点的权值大
		insert(root->rchild, v);
		updateHeight(root);
		if (getBalanceFactor(root) == -2)
		{
			if (getBalanceFactor(root->rchild) == -1)
			{
				//RR型
				L(root);
			}
			else if (getBalanceFactor(root->rchild) == 1)
			{
				//RL型
				R(root->rchild);
				L(root);
			}
		}
	}
}
void levelorder(node*root)
{
	queue<node*> Q;
	if (root)
	{
		Q.push(root);
	}
	node *newLastNode = NULL, *LastNode = root;
	while (!Q.empty())
	{
		node*f = Q.front();
		printf("%d ", f->v);
		Q.pop();
		if (f->lchild)
		{
			Q.push(f->lchild); newLastNode = f->lchild;
		}
		if (f->rchild)
		{
			Q.push(f->rchild); newLastNode = f->rchild;
		}
		if (f == LastNode)
		{
			printf("\n");
			LastNode = newLastNode;
		}
	}
}
void NoAVLinsert(node*&root,int x)
{
	if (root == NULL)
	{
		root = newNode(x);
		return;
	}
	if (x < root->v)
	{
		NoAVLinsert(root->lchild, x);
	}
	else
	{
		NoAVLinsert(root->rchild, x);
	}
}
int main()
{
	int N;
	scanf("%d", &N);
	int v;
	node*root = NULL,*NoAVLroot = NULL;
	for (int i = 0; i < N; i++)
	{
		scanf("%d", &v);
		insert(root, v);
		NoAVLinsert(NoAVLroot, v);
	}
	levelorder(root);
	printf("以下是未经过旋转调整形成的BST的层次遍历\n");
	levelorder(NoAVLroot);
	return 0;
}
/*
输入为:
10
1 2 3 4 5 6 7 8 9 0
*/

《AVL树相关的一些操作》

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