算法心经——AVL树旋转详解

AVL树旋转详解

AVL树是高度平衡的而二叉树。它的特点是:AVL树中任何节点的两个子树的高度最大差别为1,如下图所示。

算法心经——AVL树旋转详解_第1张图片

下面我们直奔主题:如将一棵非AVL树转换为一棵AVL树。

在AVL树中进行插入或删除节点后,可能导致AVL树失去平衡。这种失去平衡的可以概括为4种姿态:LL(左左),LR(左右),RR(右右)和RL(右左)。下面给出它们的示意图,每一种类型又对应两种情况,所以细分的话共有8种情况,如图所示:
算法心经——AVL树旋转详解_第2张图片
算法心经——AVL树旋转详解_第3张图片

尽管有八种之多的情况,但总结起来,其实只有LL(左左),LR(左右),RR(右右)和RL(右左)这四大类,下面对这四大类情况进行讨论:


LL类型

算法心经——AVL树旋转详解_第4张图片
我们只需要关心K1和K2。把K1的右子树挂到K2的左子树上,然后将K2挂到K1的右子树上。形象点说,就是K1左肩膀挑了一大袋子货物,为了平衡右肩膀它只好将整个K2挑了起来。这么说可能还是有些绕,记下来这张图就可以理解了。下面给出旋转代码:

node* LLrotation(node* k2) {//给出当前根节点,返回调整后的新节点
	node* k1 = k2->left;
	k2->left = k1->right;
	k1->right = k2;
	return k1;
}

RR类型

算法心经——AVL树旋转详解_第5张图片

同样只需要关心K1和K2。RR是LL的镜像,小伙伴们可以对照记忆。

node* RRrotation(node* k1) {//给出当前根节点,返回调整后的新节点
	node*k2 = k1->right;
	k1->right = k2->left;
	k2->left = k1;
	return k2;
}
LR类型

算法心经——AVL树旋转详解_第6张图片
LR和RL是上面两种方法的组合:先看K3的左子树,是不是特别像上面讲的RR那张图,所以第一步就是以K1为根节点的RR旋转;旋转之后得到中间这棵树,是不是有很像LL那张图?,所以接下来就是以K3为根节点的LL旋转,最后得到结果。

node* LRrotation(node* k3) {//给出当前根节点,返回调整后的新节点
	k3->left = RRrotation(k3->left);
	return LLrotation(k3);
}
RL类型

算法心经——AVL树旋转详解_第7张图片
RL类型是LR类型的镜像,同样只关心标出来的绿色部分,和前面对照记忆。

node* RLrotation(node* k1) {
	k1->right = LLrotation(k1->right);
	return RRrotation(k1);
}
总结一下,我认为那些旋转规则过于啰嗦,也不方便记忆,最后四种类型给出的四张图是精髓,写代码时,画一画,旋转思路立马就有了。

——THE END——
参考资料:1. https://www.cnblogs.com/skywang12345/p/3577360.html 2. https://www.cnblogs.com/coding-nerver-die/p/10975599.html

你可能感兴趣的:(心得体会,算法心经——AVL树旋转详解)