这里关于AVL平衡二叉树的 左右子树进行旋转的方法做一个概述
一般来讲:当一个二叉排序树的左右子树高的差的绝对值大于1时,为了索引效率我们会考虑以某个结点为根节点的二叉树的左右子树考虑进行左旋转或者右旋转来达到索引优化的目的,也就是我们所说的AVL平衡二叉树
这是里构建二叉树的节点类的基本属性
class Node {
int value;
Node left;
Node right;
...
...
}
返回以某个结点为根节点的树的高度
// 返回树的高度
public int height() {
return Math.max(left == null ? 0 : left.height(), right == null ? 0
: right.height()) +1;
}
返回左右子树高度
// 返回左子树高度
public int leftHeight() {
if (left == null) {
return 0;
}
return left.height();
}
// 返回右子树高度
public int rightHeight() {
if (right == null) {
return 0;
}
return right.height();
}
以某个结点向左旋转平衡二叉树高度
private void leftRotate(){
//创建新的结点
Node newNode=new Node(value);
//把新的结点的左子树设置为当前结点的左子树
newNode.left=left;
//把新的结点的右子树设置成,当前节点的右子树的左子树
newNode.right=right.left;
//把当前结点的值换成右子树的值
value=right.value;
//把当前结点的右子树设置为右子树的右子树
right=right.right;
//把当前结点的左子节点设置为新的结点
left=newNode;
}
向右旋转来平衡二叉树
//右旋转的方法和左旋转原理相同,这里就不写注释了
private void rightRotate(){
Node newNode=new Node(value);
newNode.right=right;
newNode.left=left.right;
value=left.value;
left=left.left;
right=newNode;
}
最后也是最重要的过程:在添加结点至二叉树排序树的过程中,需要判断双旋转的条件,来确保最后是一课AVL平衡二叉树,主要代码如下↓
public void add(Node node) {
if (node == null) {
return;
}
if (node.value < this.value) {
if (this.left == null) {
this.left = node;
} else {
this.left.add(node);// 递归添加
}
}else {
if (this.right == null) {
this.right = node;
} else {
this.right.add(node);
}
}
// 当添加完一个节点后左右子树高度绝对值大于1
if (rightHeight() - leftHeight() > 1) {
//如果它的右子树的左子树的高度大于它的右子树的高度
//先对他的右子结点进行右旋转,然后再对当前结点进行左旋转
if(right!=null&&right.left.height()>right.rightHeight()){
right.rightRotate();
leftRotate();
}else{
///直接左旋转
leftRotate();
}
return;//加上返回,避免继续判断
}
//当添加完一个结点,如果左子树高度-右子树高度>1,则右旋转
if(leftHeight()-rightHeight()>1){
//如果他的左子树的右子树的高度大于他的左子树的高度
if(left!=null&&left.rightHeight()>left.leftHeight()){
//先对当前节点的左子树进行左旋转
left.leftRotate();
//再对当前结点进行右旋转
rightRotate();
}
else{
//直接右旋转
rightRotate();
}
}
}
以上就是关于构建AVL平衡二叉树的旋转过程原理的 简单概述
文章来源:MyITwords APP
作者:cdy