对添加节点时,判断后进行双旋转即可实现自平衡
/**
* @author Drug
* @create 2020-05-09 11:19
*/
public class AVLTreeDemo {
public static void main(String[] args) {
// int[] arr = {4,3,6,5,7,8};
int[] arr = {10, 11, 7, 6, 8, 9};
AVLTree avlTree = new AVLTree();
for (int i : arr) {
avlTree.add(new Node(i));
}
System.out.println("旋转后的树高:" + avlTree.root.hight());
System.out.println("左子树高度:" + avlTree.root.leftHight());
System.out.println("右子树高度:" + avlTree.root.rightHight());
System.out.println("当前root节点是 " + avlTree.root);
System.out.println("当前root的左节点是 " + avlTree.root.left);
System.out.println("当前root的右节点是 " + avlTree.root.right);
}
}
class AVLTree {
//根节点
Node root;
/**
* 添加节点
*
* @param node
*/
public void add(Node node) {
//根节点为空
if (root == null) {
root = node;
} else {
//根节点不为空
root.add(node);
}
}
/**
* 中序遍历
*/
public void fixOrder() {
if (root == null) {
System.out.println("空树");
} else {
root.fixOrder();
}
}
/**
* 查找节点
*
* @param value
* @return
*/
public Node search(int value) {
if (root == null) {
return null;
}
return root.search(value);
}
/**
* 查询父节点
*
* @param value
* @return
*/
public Node searchParent(int value) {
if (root == null) {
return null;
}
return root.searchParent(value);
}
/**
* 删除并返回节点右子树的最小节点
*
* @param node
* @return
*/
public Node deleteRightTreeMin(Node node) {
//目标节点
Node target = node;
//找到右子树最小的节点
while (target.left != null) {
target = target.left;
}
//删除右子树最小节点
delete(target.value);
//返回节点
return target;
}
/**
* 删除给定节点
*
* @param value
*/
public void delete(int value) {
//根节点为空
if (root == null) {
return;
}
//查询目标节点
Node target = search(value);
//目标节点为空
if (target == null) {
return;
}
//目标节点不为空
//如果是根节点
if (root.left == null && root.right == null) {
root = null;
} else {
Node parent = searchParent(value);
//判断target是不是叶子节点
if (target.left == null && target.right == null) {
//待删除的是父节点的左子节点
if (parent.left != null && parent.left.value == value) {
parent.left = null;
return;
}
//待删除的是父节点的右子节点
if (parent.right != null && parent.right.value == value) {
parent.right = null;
return;
}
} else if (target.left != null && target.right != null) {
//target有左右子节点
Node newNode = deleteRightTreeMin(target.right);
target.value = newNode.value;
} else {
//target只有一个子节点
if (target.left != null) {
//target有左子节点
//target是parent的左子节点
if (parent != null) {
if (parent.left == target) {
parent.left = target.left;
} else {
//target是parent的右子节点
parent.right = target.right;
}
} else {
root = target.left;
}
} else {
//target有右子节点
//target是parent的左子节点
if (parent != null) {
if (parent.left == target) {
parent.left = target.right;
} else {
//target是parent的右子节点
parent.right = target.right;
}
} else {
root = target.right;
}
}
}
}
}
}
class Node {
int value;
Node left;
Node right;
public Node(int value) {
this.value = value;
}
/**
* 添加节点
*
* @param node
*/
public void add(Node node) {
//添加的节点数据大
if (this.value < node.value) {
if (this.right == null) {
//右节点为空
this.right = node;
} else {
//右节点不为空
this.right.add(node);
}
} else {
//添加的节点数据小于等于左节点
if (this.left == null) {
//左节点为空
this.left = node;
} else {
this.left.add(node);
}
}
//左旋转
if (rightHight() - leftHight() > 1) {
if (right != null && right.leftHight() > right.rightHight()) {
//如果右子树的左子树高度大于右子树的右子树高度,需要额外处理
//先右旋转平衡当前节点右子树
right.rightRotate();
}
//左旋转
leftRotate();
return;
}
//右旋转
if (leftHight() - rightHight() > 1) {
if (left != null && left.rightHight() > left.leftHight()) {
//如果左子树的右子树大于左子树的左子树高度
//先对左子树进行坐旋转自平衡
left.leftRotate();
}
//右旋转
rightRotate();
}
}
/**
* 中序遍历
*/
public void fixOrder() {
if (this.left != null) {
this.left.fixOrder();
}
System.out.println(this);
if (this.right != null) {
this.right.fixOrder();
}
}
@Override
public String toString() {
return "Node{" +
"value=" + value +
'}';
}
/**
* 查找值的节点
*
* @param value
* @return
*/
public Node search(int value) {
if (this.value == value) {
return this;
}
//查找值小于当前节点值
if (value < this.value) {
if (this.left != null) {
return this.left.search(value);
} else {
//没有找到
System.out.println("没有找到");
return null;
}
} else {
//查找值大于等于当前节点值
if (this.right != null) {
return this.right.search(value);
} else {
//没有找到
System.out.println("没有找到");
return null;
}
}
}
/**
* 查找给定值的父节点
*
* @param value
* @return
*/
public Node searchParent(int value) {
//如果左子节点或者右子节点值等于给定值,返回当前节点
if ((this.left != null && this.left.value == value) ||
(this.right != null && this.right.value == value)) {
return this;
}
//给定值小于当前节点值
if (value < this.value) {
//左子节点不为空
if (this.left != null) {
return this.left.searchParent(value);
} else {
//左子节点为空
return null;
}
} else {
//给定值大于等于当前节点值
if (this.right != null) {
return this.right.searchParent(value);
} else {
//右子节点为空
return null;
}
}
}
/**
* 返回当前节点为root的高度
*
* @param
* @return
*/
public int hight() {
return Math.max((left == null ? 0 : left.hight()), (right == null ? 0 : right.hight())) + 1;
}
/**
* 返回左子树高度
*
* @param
* @return
*/
public int leftHight() {
if (left == null) {
return 0;
}
return left.hight();
}
/**
* 返回右子树高度
*/
public int rightHight() {
if (right == null) {
return 0;
}
return right.hight();
}
/**
* 左旋转
*/
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;
}
}