二叉搜索树自动调整平衡(左右子树高度差小于等于1)——平衡二叉树
目录
1.编写测试程序,测试二叉树的四种平衡操作
public class AVLTree {
public static void main(String[] args) {
//验证插入操作
BalancedBinaryTree test0 = new BalancedBinaryTree(100);
test0.insert(50);
test0.insert(200);
System.out.print("草稿纸上运算为{100,50,200}: ");
test0.preOrder();
System.out.println();
//验证LL旋转
//发生在root
BalancedBinaryTree test1 = new BalancedBinaryTree(100);
test1.insert(70);
test1.insert(30);
test1.insert(10);
test1.insert(5);
System.out.print("草稿纸上运算为{70,10,5,30,100}: ");
test1.preOrder();
System.out.println();
//发生在非root
BalancedBinaryTree test4 = new BalancedBinaryTree(100);
test4.insert(50);
test4.insert(200);
test4.insert(150);
test4.insert(130);
System.out.print("草稿纸上运算为{100,50,150,130,200 }: ");
test4.preOrder();
System.out.println();
//验证RR旋转
//发生在root
BalancedBinaryTree test2 = new BalancedBinaryTree(100);
test2.insert(200);
test2.insert(300);
test2.insert(400);
test2.insert(500);
System.out.print("草稿纸上运算为{200,100,400,300,500}: ");
test2.preOrder();
System.out.println();
//发生在非root
BalancedBinaryTree test3 = new BalancedBinaryTree(100);
test3.insert(50);
test3.insert(200);
test3.insert(75);
test3.insert(80);
System.out.print("草稿纸上运算为{100,75,50,80,200}: ");
test3.preOrder();
System.out.println();
//验证LR旋转
BalancedBinaryTree test5 = new BalancedBinaryTree(100);
test5.insert(50);
test5.insert(200);
test5.insert(75);
test5.insert(30);
test5.insert(80);
System.out.print("LR草稿纸上运算为{75,50,30,100,80,200}: ");
test5.preOrder();
System.out.println();
//验证RL旋转
BalancedBinaryTree test6 = new BalancedBinaryTree(100);
test6.insert(50);
test6.insert(200);
test6.insert(150);
test6.insert(300);
test6.insert(125);
System.out.print("RL草稿纸上运算为{150,100,50,125,200,300}: ");
test6.preOrder();
System.out.println();
//验证删除操作
BalancedBinaryTree test7 = new BalancedBinaryTree(100);
test7.insert(50);
test7.insert(200);
test7.insert(150);
test7.insert(300);
test7.insert(25);
test7.insert(75);
System.out.print("delete草稿纸上运算为{100,50,25,75,200,150,300}: ");
test7.preOrder();
System.out.println();
//删除没有儿子的节点
test7.delete(150);
System.out.print("删除没有儿子的节点150,delete草稿纸上运算为{100 50 25 75 200 300 }: ");
test7.preOrder();
System.out.println();
//删除有一个儿子的节点
test7.delete(200);
System.out.print("删除有一个儿子的节点200,delete草稿纸上运算为{100 50 25 75 200 300 }: ");
test7.preOrder();
System.out.println();
//删除有两个儿子的节点
test7.delete(100);
System.out.print("删除有两个儿子的节点100,delete草稿纸上运算为{75,50,25,300}: ");
test7.preOrder();
System.out.println();
test7.delete(75);
System.out.print("删除节点75,delete草稿纸上运算为{50,25,300}: ");
test7.preOrder();
System.out.println();
test7.delete(50);
System.out.print("删除节点50,delete草稿纸上运算为{25,300}: ");
test7.preOrder();
System.out.println();
}
}
2.编写内部类:树结点
class AVLNode {
public int data;
public int depth;//当前子树深度的 depth
public int balance;
public AVLNode parent = null;//指向父节点的指针
public AVLNode left = null;
public AVLNode right = null;
public AVLNode() {
depth = 1;
balance = 0;
left = null;
right = null;
}
public AVLNode(int data) {
this.data = data;
depth = 1;
balance = 0;
left = null;
right = null;
}
}
3.根节点,类构造器
class BalancedBinaryTree {
/**
* 根节点
*/
private AVLNode root = null;
/**
* 构造器
*/
public BalancedBinaryTree() {
}
public BalancedBinaryTree(int data) {
root = new AVLNode(data);
}
//以及别的操作
}
4.插入
插入过程分为:二叉查找树的插入过程+再平衡过程
再平衡过程分为:计算深度和平衡值+进行平衡操作
public void insert(int data) {
if (root == null) {
root = new AVLNode(data);
} else {
insertSon(root, data);
}
}
private void insertSon(AVLNode node, int data) {
if (data < node.data) {
if (node.left != null) {
insertSon(node.left, data);
} else {
node.left = new AVLNode(data);
node.left.parent = node;//子节点锁住parent
}
} else {
if (node.right != null) {
insertSon(node.right, data);
} else {
node.right = new AVLNode(data);
node.right.parent = node;
}
}
// 计算平衡和深度
node.balance = calculateBalance(node);
node.depth = calculateDepth(node);
// 平衡节点
balanceNode(node);
}
5.平衡
5.1计算平衡值
private int calculateBalance(AVLNode node) {
int leftDepth;
int rightDepth;
if (node.left != null) {
leftDepth = node.left.depth;
} else {
leftDepth = 0;
}
if (node.right != null) {
rightDepth = node.right.depth;
} else {
rightDepth = 0;
}
return leftDepth - rightDepth;
}
5.2.计算深度
private int calculateDepth(AVLNode node) {
int depth = 0;