平衡二叉树的定义
AVL树
-
继承结构
添加导致的失衡
四种旋转调整失衡
LL – 右旋转(单旋)
RR – 左旋转(单旋)
LR – RR左旋转,LL右旋转(双旋)
RL – LL右旋转,RR左旋转(双旋)
添加之后的修复
protected void afterAdd(Node<E> node) {
while ((node = node.parent) != null) {
if (isBalanced(node)) {
// 更新高度
updateHeight(node);
} else {
// 恢复平衡
rebalance(node);
}
}
}
/**
* 恢复平衡
*
* @param grand 第一个不平衡的父节点
*/
private void rebalance(Node<E> grand) {
Node<E> parent = ((AVLNode<E>) grand).tallerChild();
Node<E> node = ((AVLNode<E>) parent).tallerChild();
if (parent.isLeftChild()) { // L
if (node.isLeftChild()) { // LL
rotateRight(grand);
} else { // LR
rotateLeft(parent);
rotateRight(grand);
}
} else { // R
if (node.isLeftChild()) { // RL
rotateRight(parent);
rotateLeft(grand);
} else { // RR
rotateLeft(grand);
}
}
}
旋转
private void rotateLeft(Node<E> grand) {
Node<E> parent = grand.right;
Node<E> child = parent.left;
grand.right = child;
parent.left = grand;
afterRotate(grand, parent, child);
}
private void rotateRight(Node<E> grand) {
Node<E> parent = grand.left;
Node<E> child = parent.right;
grand.left = child;
parent.right = grand;
afterRotate(grand, parent, child);
}
private void afterRotate(Node<E> grand, Node<E> parent, Node<E> child) {
// 让parent称为子树的根节点
parent.parent = grand.parent;
if (grand.isLeftChild()) {
grand.parent.left = parent;
} else if (grand.isRightChild()) {
grand.parent.right = parent;
} else { // grand是root节点
root = parent;
}
// 更新child的parent
if (child != null) {
child.parent = grand;
}
// 更新grand的parent
grand.parent = parent;
// 更新高度
updateHeight(grand);
updateHeight(parent);
}
例子
统一所有旋转操作
四种旋转操作最后的结果都是一样的,按照a,b,c,d,e,f,g大小来排列
private void rebalance(Node<E> grand) {
Node<E> parent = ((AVLNode<E>) grand).tallerChild();
Node<E> node = ((AVLNode<E>) parent).tallerChild();
if (parent.isLeftChild()) { // L
if (node.isLeftChild()) { // LL
rotate(grand, node, node.right, parent, parent.right, grand);
} else { // LR
rotate(grand, parent, node.left, node, node.right, grand);
}
} else { // R
if (node.isLeftChild()) { // RL
rotate(grand, grand, node.left, node, node.right, parent);
} else { // RR
rotate(grand, grand, parent.left, parent, node.left, node);
}
}
}
private void rotate(
Node<E> r, // 子树的根节点
Node<E> b, Node<E> c,
Node<E> d,
Node<E> e, Node<E> f) {
// 让d成为这棵子树的根节点
d.parent = r.parent;
if (r.isLeftChild()) {
r.parent.left = d;
} else if (r.isRightChild()) {
r.parent.right = d;
} else {
root = d;
}
//b-c
b.right = c;
if (c != null) {
c.parent = b;
}
updateHeight(b);
// e-f
f.left = e;
if (e != null) {
e.parent = f;
}
updateHeight(f);
// b-d-f
d.left = b;
d.right = f;
b.parent = d;
f.parent = d;
updateHeight(d);
}
删除导致的失衡
删除之后的修复
protected void afterRemove(Node<E> node) {
while ((node = node.parent) != null) {
if (isBalanced(node)) {
// 更新高度
updateHeight(node);
} else {
// 恢复平衡
rebalance(node);
}
}
}
总结
总代码
-
AVLTree
import java.util.Comparator; public class AVLTree<E> extends BST<E> { public AVLTree() { this(null); } public AVLTree(Comparator<E> comparator) { super(comparator); } @Override protected void afterAdd(Node<E> node) { while ((node = node.parent) != null) { if (isBalanced(node)) { // 更新高度 updateHeight(node); } else { // 恢复平衡 rebalance(node); // 整棵树恢复平衡 break; } } } @Override protected void afterRemove(Node<E> node) { while ((node = node.parent) != null) { if (isBalanced(node)) { // 更新高度 updateHeight(node); } else { // 恢复平衡 rebalance(node); } } } @Override protected Node<E> createNode(E element, Node<E> parent) { return new AVLNode<>(element, parent); } /** * 恢复平衡 * * @param grand 高度最低的那个不平衡节点 */ @SuppressWarnings("unused") private void rebalance2(Node<E> grand) { Node<E> parent = ((AVLNode<E>) grand).tallerChild(); Node<E> node = ((AVLNode<E>) parent).tallerChild(); if (parent.isLeftChild()) { // L if (node.isLeftChild()) { // LL rotateRight(grand); } else { // LR rotateLeft(parent); rotateRight(grand); } } else { // R if (node.isLeftChild()) { // RL rotateRight(parent); rotateLeft(grand); } else { // RR rotateLeft(grand); } } } /** * 恢复平衡 * * @param grand 高度最低的那个不平衡节点 */ private void rebalance(Node<E> grand) { Node<E> parent = ((AVLNode<E>) grand).tallerChild(); Node<E> node = ((AVLNode<E>) parent).tallerChild(); if (parent.isLeftChild()) { // L if (node.isLeftChild()) { // LL rotate(grand, node, node.right, parent, parent.right, grand); } else { // LR rotate(grand, parent, node.left, node, node.right, grand); } } else { // R if (node.isLeftChild()) { // RL rotate(grand, grand, node.left, node, node.right, parent); } else { // RR rotate(grand, grand, parent.left, parent, node.left, node); } } } private void rotate( Node<E> r, // 子树的根节点 Node<E> b, Node<E> c, Node<E> d, Node<E> e, Node<E> f) { // 让d成为这棵子树的根节点 d.parent = r.parent; if (r.isLeftChild()) { r.parent.left = d; } else if (r.isRightChild()) { r.parent.right = d; } else { root = d; } //b-c b.right = c; if (c != null) { c.parent = b; } updateHeight(b); // e-f f.left = e; if (e != null) { e.parent = f; } updateHeight(f); // b-d-f d.left = b; d.right = f; b.parent = d; f.parent = d; updateHeight(d); } private void rotateLeft(Node<E> grand) { Node<E> parent = grand.right; Node<E> child = parent.left; grand.right = child; parent.left = grand; afterRotate(grand, parent, child); } private void rotateRight(Node<E> grand) { Node<E> parent = grand.left; Node<E> child = parent.right; grand.left = child; parent.right = grand; afterRotate(grand, parent, child); } private void afterRotate(Node<E> grand, Node<E> parent, Node<E> child) { // 让parent称为子树的根节点 parent.parent = grand.parent; if (grand.isLeftChild()) { grand.parent.left = parent; } else if (grand.isRightChild()) { grand.parent.right = parent; } else { // grand是root节点 root = parent; } // 更新child的parent if (child != null) { child.parent = grand; } // 更新grand的parent grand.parent = parent; // 更新高度 updateHeight(grand); updateHeight(parent); } private boolean isBalanced(Node<E> node) { return Math.abs(((AVLNode<E>) node).balanceFactor()) <= 1; } private void updateHeight(Node<E> node) { ((AVLNode<E>) node).updateHeight(); } private static class AVLNode<E> extends Node<E> { int height = 1; public AVLNode(E element, Node<E> parent) { super(element, parent); } public int balanceFactor() { int leftHeight = left == null ? 0 : ((AVLNode<E>) left).height; int rightHeight = right == null ? 0 : ((AVLNode<E>) right).height; return leftHeight - rightHeight; } public void updateHeight() { int leftHeight = left == null ? 0 : ((AVLNode<E>) left).height; int rightHeight = right == null ? 0 : ((AVLNode<E>) right).height; height = 1 + Math.max(leftHeight, rightHeight); } public Node<E> tallerChild() { int leftHeight = left == null ? 0 : ((AVLNode<E>) left).height; int rightHeight = right == null ? 0 : ((AVLNode<E>) right).height; if (leftHeight > rightHeight) return left; if (leftHeight < rightHeight) return right; return isLeftChild() ? left : right; } @Override public String toString() { String parentString = "null"; if (parent != null) { parentString = parent.element.toString(); } return element + "_p(" + parentString + ")_h(" + height + ")"; } } }
-
BST
@SuppressWarnings("unchecked") public class BST<E> extends BinaryTree<E> { private Comparator<E> comparator; public BST() { this(null); } public BST(Comparator<E> comparator) { this.comparator = comparator; } public void add(E element) { elementNotNullCheck(element); // 添加第一个节点 if (root == null) { root = createNode(element, null); size++; // 新添加节点之后的处理 afterAdd(root); return; } // 添加的不是第一个节点 // 找到父节点 Node<E> parent = root; Node<E> node = root; int cmp = 0; do { cmp = compare(element, node.element); parent = node; if (cmp > 0) { node = node.right; } else if (cmp < 0) { node = node.left; } else { // 相等 node.element = element; return; } } while (node != null); // 看看插入到父节点的哪个位置 Node<E> newNode = createNode(element, parent); if (cmp > 0) { parent.right = newNode; } else { parent.left = newNode; } size++; // 新添加节点之后的处理 afterAdd(newNode); } /** * 添加node之后的调整 * * @param node 新添加的节点 */ protected void afterAdd(Node<E> node) { } /** * 删除node之后的调整 * * @param node 被删除的节点 */ protected void afterRemove(Node<E> node) { } public void remove(E element) { remove(node(element)); } public boolean contains(E element) { return node(element) != null; } private void remove(Node<E> node) { if (node == null) return; size--; if (node.hasTwoChildren()) { // 度为2的节点 // 找到后继节点 Node<E> s = successor(node); // 用后继节点的值覆盖度为2的节点的值 node.element = s.element; // 删除后继节点 node = s; } // 删除node节点(node的度必然是1或者0) Node<E> replacement = node.left != null ? node.left : node.right; if (replacement != null) { // node是度为1的节点 // 更改parent replacement.parent = node.parent; // 更改parent的left、right的指向 if (node.parent == null) { // node是度为1的节点并且是根节点 root = replacement; } else if (node == node.parent.left) { node.parent.left = replacement; } else { // node == node.parent.right node.parent.right = replacement; } // 删除节点之后的处理 afterRemove(node); } else if (node.parent == null) { // node是叶子节点并且是根节点 root = null; // 删除节点之后的处理 afterRemove(node); } else { // node是叶子节点,但不是根节点 if (node == node.parent.left) { node.parent.left = null; } else { // node == node.parent.right node.parent.right = null; } // 删除节点之后的处理 afterRemove(node); } } private Node<E> node(E element) { Node<E> node = root; while (node != null) { int cmp = compare(element, node.element); if (cmp == 0) return node; if (cmp > 0) { node = node.right; } else { // cmp < 0 node = node.left; } } return null; } /** * @return 返回值等于0,代表e1和e2相等;返回值大于0,代表e1大于e2;返回值小于于0,代表e1小于e2 */ private int compare(E e1, E e2) { if (comparator != null) { return comparator.compare(e1, e2); } return ((Comparable<E>) e1).compareTo(e2); } private void elementNotNullCheck(E element) { if (element == null) { throw new IllegalArgumentException("element must not be null"); } } }
-
BinaryTree
public class BinaryTree<E> implements BinaryTreeInfo { protected int size; protected Node<E> root; public int size() { return size; } public boolean isEmpty() { return size == 0; } public void clear() { root = null; size = 0; } public void preorder(Visitor<E> visitor) { if (visitor == null) return; preorder(root, visitor); } private void preorder(Node<E> node, Visitor<E> visitor) { if (node == null || visitor.stop) return; visitor.stop = visitor.visit(node.element); preorder(node.left, visitor); preorder(node.right, visitor); } public void inorder(Visitor<E> visitor) { if (visitor == null) return; inorder(root, visitor); } private void inorder(Node<E> node, Visitor<E> visitor) { if (node == null || visitor.stop) return; inorder(node.left, visitor); if (visitor.stop) return; visitor.stop = visitor.visit(node.element); inorder(node.right, visitor); } public void postorder(Visitor<E> visitor) { if (visitor == null) return; postorder(root, visitor); } private void postorder(Node<E> node, Visitor<E> visitor) { if (node == null || visitor.stop) return; postorder(node.left, visitor); postorder(node.right, visitor); if (visitor.stop) return; visitor.stop = visitor.visit(node.element); } public void levelOrder(Visitor<E> visitor) { if (root == null || visitor == null) return; Queue<Node<E>> queue = new LinkedList<>(); queue.offer(root); while (!queue.isEmpty()) { Node<E> node = queue.poll(); if (visitor.visit(node.element)) return; if (node.left != null) { queue.offer(node.left); } if (node.right != null) { queue.offer(node.right); } } } public boolean isComplete() { if (root == null) return false; Queue<Node<E>> queue = new LinkedList<>(); queue.offer(root); boolean leaf = false; while (!queue.isEmpty()) { Node<E> node = queue.poll(); if (leaf && !node.isLeaf()) return false; if (node.left != null) { queue.offer(node.left); } else if (node.right != null) { return false; } if (node.right != null) { queue.offer(node.right); } else { // 后面遍历的节点都必须是叶子节点 leaf = true; } } return true; } public int height() { if (root == null) return 0; // 树的高度 int height = 0; // 存储着每一层的元素数量 int levelSize = 1; Queue<Node<E>> queue = new LinkedList<>(); queue.offer(root); while (!queue.isEmpty()) { Node<E> node = queue.poll(); levelSize--; if (node.left != null) { queue.offer(node.left); } if (node.right != null) { queue.offer(node.right); } if (levelSize == 0) { // 意味着即将要访问下一层 levelSize = queue.size(); height++; } } return height; } public int height2() { return height(root); } private int height(Node<E> node) { if (node == null) return 0; return 1 + Math.max(height(node.left), height(node.right)); } protected Node<E> createNode(E element, Node<E> parent) { return new Node<>(element, parent); } protected Node<E> predecessor(Node<E> node) { if (node == null) return null; // 前驱节点在左子树当中(left.right.right.right....) Node<E> p = node.left; if (p != null) { while (p.right != null) { p = p.right; } return p; } // 从父节点、祖父节点中寻找前驱节点 while (node.parent != null && node == node.parent.left) { node = node.parent; } // node.parent == null // node == node.parent.right return node.parent; } protected Node<E> successor(Node<E> node) { if (node == null) return null; // 前驱节点在左子树当中(right.left.left.left....) Node<E> p = node.right; if (p != null) { while (p.left != null) { p = p.left; } return p; } // 从父节点、祖父节点中寻找前驱节点 while (node.parent != null && node == node.parent.right) { node = node.parent; } return node.parent; } public static abstract class Visitor<E> { boolean stop; /** * @return 如果返回true,就代表停止遍历 */ abstract boolean visit(E element); } protected static class Node<E> { E element; Node<E> left; Node<E> right; Node<E> parent; public Node(E element, Node<E> parent) { this.element = element; this.parent = parent; } public boolean isLeaf() { return left == null && right == null; } public boolean hasTwoChildren() { return left != null && right != null; } public boolean isLeftChild() { return parent != null && this == parent.left; } public boolean isRightChild() { return parent != null && this == parent.right; } public Node<E> sibling() { if (isLeftChild()) { return parent.right; } if (isRightChild()) { return parent.left; } return null; } } @Override public Object root() { return root; } @Override public Object left(Object node) { return ((Node<E>) node).left; } @Override public Object right(Object node) { return ((Node<E>) node).right; } @Override public Object string(Object node) { return node; } }
Comments | 0 条评论