AVL是BST的升级版,搜索性能更高。
function Node(key) {
this.data = key
this.left = null
this.right = null
}
function AVL(arr) {
this.root = null
this.createAVL(arr)
}
AVL.prototype.createAVL = function(arr) {
const len = arr.length
if(len === 0) return null
let root = null
const res = []
for(let i = 0;i < len; i++) {
if(res.indexOf(arr[i]) === -1) {
root = this.insertNode(root, arr[i])
res.push(arr[i])
}
}
this.root = root
}
// RR型左旋
AVL.prototype.rotateL = function(AvlNode) {
var node = AvlNode.right; // 保存右子节点
AvlNode.right = node.left; // node的左子节点连接到AvlNode成为其右子节点
node.left = AvlNode; // AvlNode连接到node成为其左子节点
return node; // 返回node,连接到AvlNode最初的父节点
}
// LL型右旋
AVL.prototype.rotateR = function(AvlNode) {
var node = AvlNode.left;
AvlNode.left = node.right;
node.right = AvlNode;
return node
}
// RL型
AVL.prototype.rotateRL = function(AvlNode) {
AvlNode.right = this.rotateR(AvlNode.right)
return this.rotateL(AvlNode)
}
// LR型
AVL.prototype.rotateLR = function(AvlNode) {
AvlNode.left = this.rotateL(AvlNode.left)
return this.rotateR(AvlNode)
}
// 获取高度
AVL.prototype.getHeight = function(node) {
if(node === null) {
return 0
}
return Math.max(this.getHeight(node.left), this.getHeight(node.right)) + 1
}
AVL.prototype.balanceAVL = function(root) {
if(root === null) return root
let lHeight = this.getHeight(root.left)
let rHeight = this.getHeight(root.right)
if(lHeight - rHeight === 2) {
let ll = this.getHeight(root.left.left)
let lr = this.getHeight(root.left.right)
if(ll - lr === 1) {
root = this.rotateR(root) // LL型
} else {
root = this.rotateLR(root)//LR型
}
}
else if(rHeight - lHeight === 2) {
let rl = this.getHeight(root.right.left)
let rr = this.getHeight(root.right.right)
if(rr - rl === 1) { //RR型
root = this.rotateL(root)
} else {
root = this.rotateRL(root)
}
}
return root
}
AVL.prototype.insertNode = function(node, key) {
if(node === null) {
node = new Node(key)
} else {
if(key < node.data) {
node.left = this.insertNode(node.left, key)
node = this.balanceAVL(node)
} else if(key > node.data) {
node.right = this.insertNode(node.right, key)
node = this.balanceAVL(node)
}
}
return node
}
AVL.prototype.deleteNode = function(node, key) { // 返回删除后的值
if(node === null) {
return node
} else {
if(key === node.data) {
if(node.left === null && node.right === null) return null // 直接删除该节点
if(node.left === null && node.right !== null) {
node = node.right
return node
}
else if(node.right === null && node.left !== null) {
node = node.left
return node
} else {
// 左右节点都有的
node.data = node.right.data
node.right = this.deleteNode(node.right, key)
node = this.balanceAVL(node)
}
}
else if(key < node.data) {
// 将后面的值复制上来,然后递归删除
node.left = this.deleteNode(node.left, key)
node = this.balanceAVL(node)
} else {
node.right = this.deleteNode(node.right, key)
node = this.balanceAVL(node)
}
}
return node
}
const AVLobj = new AVL([2,3,9,1])