AVL树相关的一些操作
Posted wx630c98f24f6b8
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了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树相关的一些操作的主要内容,如果未能解决你的问题,请参考以下文章