自平衡二叉树:
平衡二叉树也叫平衡二叉搜索树(self-balancing binary search tree),又被称为AVL树,可以保证查询效率较高。平衡二叉树的左右两颗子树的高度差的绝对值不超过1,并且左右子树都是平衡二叉树。如下图中:1,2为平衡二叉树,3则不是。
以下由浅入深讨论如何将一棵树转换为AVL树:
首先简单讨论右子树高度 - 左子树高度 > 1 的情况:
左子树高度 - 右子树高度 > 1 的情况:
我们可以看到,前面的两个数列,进行单旋转(即一次旋转)就可以将非平衡二叉树转成平衡二叉树,但是在某些情况下,单旋转不能完成平衡二叉树的转换。比如数列{10, 11, 7, 6, 8, 9}
当符合左旋转条件时,根据上述方法类推即可。
代码实现:
package DataStructure;
public class AVLTreeDemo {
public static void main(String[] args) {
// int[] arr = {4, 3, 6, 5, 7, 8};
// int[] arr = {10, 12, 8, 9, 7, 6};
int[] arr = {10, 11, 7, 6, 8, 9};
// int[] arr = {2, 4, 7, 5, 8, 3};
AVLTree avl = new AVLTree();
for (int num : arr) {
avl.add(new AVLNode(num));
}
System.out.println("平衡后:");
avl.midOrder();
System.out.println("树的高度:" + avl.root.treeHeight());
System.out.println("左子树的高度:" + avl.root.leftTreeHeight());
System.out.println("右子树的高度:" + avl.root.rightTreeHeight());
}
}
class AVLTree {
public AVLNode root = null;
public void add(AVLNode node) {
if (root == null) {
root = node;
}else {
root.add(node);
}
}
public void midOrder() {
if (root != null) {
root.midOrder();
}
}
}
class AVLNode {
public int value;
public AVLNode left;
public AVLNode right;
public AVLNode() {
}
public AVLNode(int value) {
this.value = value;
}
// 每添加一个节点,都对树进行平衡操作:
public void add(AVLNode 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);
}
}
if (this.rightTreeHeight() - this.leftTreeHeight() > 1) {
if (this.right != null && this.right.leftTreeHeight() > this.right.rightTreeHeight()) {
this.right.rightRotate();;
}
this.leftRotate();
}else if (this.leftTreeHeight() - this.rightTreeHeight() > 1) {
if (this.left != null && this.left.rightTreeHeight() > this.left.leftTreeHeight()) {
this.left.leftRotate();
}
this.rightRotate();
}
}
// 中序遍历
public void midOrder() {
if (this.left != null) {
this.left.midOrder();
}
System.out.println(this);
if (this.right != null) {
this.right.midOrder();
}
}
@Override
public String toString() {
return "BSTNode{" +
"value=" + value +
'}';
}
// 获取以当前节点为根节点的树的高度:
public int treeHeight() {
return Math.max(left == null ? 0 : left.treeHeight(), right == null ? 0 : right.treeHeight()) + 1;
}
// 获取当前节点左子树的高度
public int leftTreeHeight() {
if (left == null) {
return 0;
}
return left.treeHeight();
}
// 获取当前节点右子树的高度
public int rightTreeHeight() {
if (right == null) {
return 0;
}
return right.treeHeight();
}
// 左旋转
private void leftRotate() {
AVLNode newNode = new AVLNode(this.value);
newNode.left = this.left;
newNode.right = this.right.left;
this.value = this.right.value;
this.left = newNode;
this.right = this.right.right;
}
// 右旋转
private void rightRotate() {
AVLNode newNode = new AVLNode(this.value);
newNode.right = this.right;
newNode.left = this.left.right;
this.value = this.left.value;
this.right = newNode;
this.left = this.left.left;
}
}