class AVLTree extends BinarySearchTree {
constructor(compareFn = defaultCompare) {
super(compareFn);
this.compareFn = compareFn;
this.root = null;
}
}
getNodeHeight(node) {
if (node == null) {
return -1;
}
return Math.max(this.getNodeHeight(node.left),
this.getNodeHeight(node.right)) + 1;
}
const BalanceFactor = {
UNBALANCED_RIGHT: 1,
SLIGHTLY_UNBALANCED_RIGHT: 2,
BALANCED: 3,
SLIGHTLY_UNBALANCED_LEFT: 4,
UNBALANCED_LEFT: 5
};
getBalanceFactor(node) {
const heightDifference = this.getNodeHeight(node.left) -
this.getNodeHeight(node.right);
switch (heightDifference) {
case -2:
return BalanceFactor.UNBALANCED_RIGHT;
case -1:
return BalanceFactor.SLIGHTLY_UNBALANCED_RIGHT;
case 1:
return BalanceFactor.SLIGHTLY_UNBALANCED_LEFT;
case 2:
return BalanceFactor.UNBALANCED_LEFT;
default:
return BalanceFactor.BALANCED;
}
}
rotationLL(node) {
//将节点X置于节点Y(平衡因子为+2)所在的位置
const tmp = node.left;
//将节点Y的左子节点置为节点X的右子节点Z
node.left = tmp.right;
//将节点X的右子节点置为节点Y
tmp.right = node;
return tmp;
}
rotationRR(node) {
//将节点X置于节点Y(平衡因子为2)所在的位置
const tmp = node.right;
//将节点Y的右子节点置为节点X的左子节点Z
node.right = tmp.left;
//将节点X的左子节点置为节点Y
tmp.left = node;
return tmp;
}
rotationLR(node) {
//先做一次RR旋转,即左旋转
node.left = this.rotationRR(node.left);
//再做一次LL旋转,即右旋转
return this.rotationLL(node);
}
rotationRL(node) {
//先做一次LL旋转,即右旋转
node.right = this.rotationLL(node.right);
//再做一次LL旋转,即左旋转
return this.rotationRR(node);
}
insert(key) {
this.root = this.insertNode(this.root, key);
}
insertNode(node, key) {
if (node == null) {
return new Node(key);
} if (this.compareFn(key, node.key) === Compare.LESS_THAN) {
node.left = this.insertNode(node.left, key);
} else if (this.compareFn(key, node.key) === Compare.BIGGER_THAN) {
node.right = this.insertNode(node.right, key);
} else {
return node; // duplicated key
}
// verify if tree is balanced
const balanceFactor = this.getBalanceFactor(node);
if (balanceFactor === BalanceFactor.UNBALANCED_LEFT) {
if (this.compareFn(key, node.left.key) === Compare.LESS_THAN) {
// Left left case
node = this.rotationLL(node);
} else {
// Left right case
return this.rotationLR(node);
}
}
if (balanceFactor === BalanceFactor.UNBALANCED_RIGHT) {
if (this.compareFn(key, node.right.key) === Compare.BIGGER_THAN) {
// Right right case
node = this.rotationRR(node);
} else {
// Right left case
return this.rotationRL(node);
}
}
return node;
}
removeNode(node, key) {
node = super.removeNode(node, key); // {1}
if (node == null) {
return node; // null,不需要进行平衡
}
// verify if tree is balanced
const balanceFactor = this.getBalanceFactor(node);
if (balanceFactor === BalanceFactor.UNBALANCED_LEFT) {
// Left left case
if (
this.getBalanceFactor(node.left) === BalanceFactor.BALANCED
|| this.getBalanceFactor(node.left) === BalanceFactor.SLIGHTLY_UNBALANCED_LEFT
) {
return this.rotationLL(node);
}
// Left right case
if (this.getBalanceFactor(node.left) === BalanceFactor.SLIGHTLY_UNBALANCED_RIGHT) {
return this.rotationLR(node.left);
}
}
if (balanceFactor === BalanceFactor.UNBALANCED_RIGHT) {
// Right right case
if (
this.getBalanceFactor(node.right) === BalanceFactor.BALANCED
|| this.getBalanceFactor(node.right) === BalanceFactor.SLIGHTLY_UNBALANCED_RIGHT
) {
return this.rotationRR(node);
}
// Right left case
if (this.getBalanceFactor(node.right) === BalanceFactor.SLIGHTLY_UNBALANCED_LEFT) {
return this.rotationRL(node.right);
}
}
return node;
}
class Node {
constructor(key) {
this.key = key; // 节点值
this.left = null; // 指向左子节点
this.right = null; // 指向右子节点
}
}
class RedBlackNode extends Node {
constructor(key) {
super(key);
this.key = key;
this.color = Colors.RED;
this.parent = null;
}
isRed() {
return this.color === Colors.RED;
}
}
class RedBlackTree extends BinarySearchTree {
constructor(compareFn = defaultCompare) {
super(compareFn);
this.compareFn = compareFn;
this.root = null;
}
}
insert(key) {
if (this.root == null) {
this.root = new RedBlackNode(key);
this.root.color = Colors.BLACK;
} else {
const newNode = this.insertNode(this.root, key);
this.fixTreeProperties(newNode);
}
}
insertNode(node, key) {
if (this.compareFn(key, node.key) === Compare.LESS_THAN) {
if (node.left == null) {
node.left = new RedBlackNode(key);
node.left.parent = node;
return node.left;
}
else {
return this.insertNode(node.left, key);
}
} else if (node.right == null) {
node.right = new RedBlackNode(key);
node.right.parent = node;
return node.right;
} else {
return this.insertNode(node.right, key);
}
}
fixTreeProperties(node) {
while (node && node.parent && node.parent.color.isRed()
&& node.color !== Colors.BLACK) {
let parent = node.parent;
const grandParent = parent.parent;
// 情形A:父节点是左侧子节点
if (grandParent && grandParent.left === parent) {
const uncle = grandParent.right;
// 情形1A:叔节点也是红色——只需要重新填色
if (uncle && uncle.color === Colors.RED) {
grandParent.color = Colors.RED;
parent.color = Colors.BLACK;
uncle.color = Colors.BLACK;
node = grandParent;
} else {
// 情形2A:节点是右侧子节点——左旋转
if (node === parent.right) {
this.rotationRR(parent);
node = parent;
parent = node.parent;
}
// 情形3A:节点是左侧子节点——右旋转
this.rotationLL(grandParent);
parent.color = Colors.BLACK;
grandParent.color = Colors.RED;
node = parent;
}
} else { // 情形B:父节点是右侧子节点
const uncle = grandParent.left;
// 情形1B:叔节点是红色——只需要重新填色
if (uncle && uncle.color === Colors.RED) {
grandParent.color = Colors.RED;
parent.color = Colors.BLACK;
uncle.color = Colors.BLACK;
node = grandParent;
} else {
// 情形2B:节点是左侧子节点——右旋转
if (node === parent.left) {
this.rotationLL(parent);
node = parent;
parent = node.parent;
}
// 情形3B:节点是右侧子节点——左旋转
this.rotationRR(grandParent);
parent.color = Colors.BLACK;
grandParent.color = Colors.RED;
node = parent;
}
}
}
this.root.color = Colors.BLACK;
}
rotationLL(node) {
const tmp = node.left
node.left = tmp.right;
if (tmp.right && tmp.right.key) {
tmp.right.parent = node;
}
tmp.parent = node.parent;
if (!node.parent) {
this.root = tmp;
} else {
if (node === node.parent.left) {
node.parent.left = tmp;
} else {
node.parent.right = tmp;
}
}
tmp.right = node; node.parent = tmp;
}
rotationRR(node) {
const tmp = node.right;
node.right = tmp.left;
if (tmp.left && tmp.left.key) {
tmp.left.parent = node;
}
tmp.parent = node.parent;
if (!node.parent) {
this.root = tmp;
} else {
if (node === node.parent.left) {
node.parent.left = tmp;
} else {
node.parent.right = tmp;
}
}
tmp.left = node; node.parent = tmp;
}
设计一个AVL树,向树中插入1,2,3,4,5,6,7,8,9,10,分别用先序、中序、后序方式遍历该树。