rank-tree
Version:
For the structure of sort sets, refer to readme for details
805 lines • 23.7 kB
JavaScript
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.RankTree = void 0;
const RB_node_1 = require("./RB_node");
class RankTree {
constructor() {
this._root = null;
this._hash = new Map();
}
/**
* 设置k-v
* @param key
* @param score
*/
tadd(key, score) {
if (this._hash.has(key)) {
this._onUpdate(key, score);
}
else {
let node = new RB_node_1.RBTreeNode(key, score);
node.setRed();
if (!this._root) {
node.setBlack();
this._root = node;
this._hash.set(key, node);
}
else {
this._onInsert(node, this._root);
}
}
}
/**
* 增加某个字段积分
* @param key
* @param add
*/
tincrease(key, add) {
if (this._hash.has(key)) {
let node = this._hash.get(key);
let score = node.score + add;
this._onUpdate(key, score);
}
else {
let node = new RB_node_1.RBTreeNode(key, add);
if (!this._root) {
node.setBlack();
this._root = node;
this._hash.set(key, node);
}
else {
this._onInsert(node, this._root);
}
}
}
/**
* 扣除指定key值的积分
* @param key
* @param mul
*/
treduce(key, mul) {
if (this._hash.has(key)) {
let node = this._hash.get(key);
let score = node.score - mul;
this._onUpdate(key, score);
}
else {
let node = new RB_node_1.RBTreeNode(key, -mul);
if (!this._root) {
node.setBlack();
this._root = node;
this._hash.set(key, node);
}
else {
this._onInsert(node, this._root);
}
}
}
/**
* 获取排名
* @param key
* @returns
*/
trank(key) {
let node = this._hash.get(key);
if (!node) {
return -1;
}
return this._onGetIndex(this._root, node, 0);
}
/**
* 指定积分的个数
* @param min
* @param max
* @returns
*/
tcount(minS, maxS) {
// 定位到起始节点后中序遍历
return this.trevrangebyscore(minS, maxS).length;
}
/**
* 红黑树节点个数
* @param min
* @param max
* @returns
*/
tcard() {
return this._hash.size;
}
/**
* 返回指定序号的元素 升序
* @param minI 1起始
* @param maxI
* @returns
*/
trange(minI, maxI = 0) {
let _min = Math.max(minI, 1);
let _max;
if (maxI == 0) {
_max = this._hash.size;
}
else {
_max = Math.min(maxI, this._hash.size);
}
let count = _max - _min + 1;
let list = new Array();
let node = this._findIndexStartNode(this._root, _min);
if (!node) {
return list;
}
this._LDR_selectIndexRange(node, list, count, _min, _min, _max);
return list;
}
/**
* 区间积分
* @param minS
* @param maxS
* @returns
*/
trevrangebyscore(minS, maxS = -1) {
let list = new Array();
let prev = this._findScoreStartNode(this._root, minS);
if (!prev) {
return list;
}
if (maxS == -1) {
maxS = Infinity;
}
this._LDR_selectScoreRange(prev, list, minS, maxS);
return list;
}
/**
* 获取所有数据
* @returns
*/
tgetall() {
let list = new Array();
this._LDR_SCORE(this._root, list, Infinity);
return list;
}
/**
* 获取元素
* @param key
* @returns
*/
tscore(key) {
let node = this._hash.get(key);
return node && node.score || 0;
}
/**
* 删除指定key
* @param key
* @returns
*/
trem(keys) {
let _keys;
if (!Array.isArray(keys)) {
_keys = [keys];
}
else {
_keys = keys;
}
_keys.forEach((key) => {
let node = this._hash.get(key);
if (!node) {
return;
}
this._onRemove(node);
this._hash.delete(key);
});
}
/**
* 获取指定序号元素·
* @param index
* @returns
*/
tgetwithindex(index) {
let node = this._findIndexStartNode(this._root, index);
if (!node) {
return null;
}
return [node.key, node.score];
}
/************************************** 以下为自调用函数 *********************************/
/**
* 寻找位置点
* @param e
* @param parent
*/
_onInsert(e, parent) {
if (this._compare(e, parent)) {
parent.index++;
if (!parent.left) {
parent.left = e;
e.parent = parent;
this._hash.set(e.key, e);
this._onTuneUp(e);
}
else {
parent = parent.left;
this._onInsert(e, parent);
}
}
else {
if (!parent.right) {
parent.right = e;
e.parent = parent;
this._hash.set(e.key, e);
this._onTuneUp(e);
}
else {
parent = parent.right;
this._onInsert(e, parent);
}
}
}
/**
* 更新积分处理
* @param key
* @param score
*/
_onUpdate(key, score) {
// 直接删除 重新添加新值, 因为
let e = this._hash.get(key);
this._onRemove(e);
let node = new RB_node_1.RBTreeNode(key, score);
this._hash.set(key, node);
if (!this._root) {
node.setBlack();
this._root = node;
this._hash.set(key, node);
}
else {
this._onInsert(node, this._root);
}
}
/**
* 移除
* @param node
* @returns
*/
_onRemove(node) {
let parent = node.parent;
if (node.isLeaf()) {
if (node.isRed()) {
// 递归调整index
// 红叶子节点 直接删除
if (node.isLeftChild()) {
parent.left = null;
node.parent.index--;
}
else {
parent.right = null;
}
}
else {
// 先修复 再删除
this._onRepairNode(node);
if (node.isLeftChild()) {
node.parent.left = null;
node.parent.index--;
}
else {
node.parent.right = null;
}
}
this._onRepairIndex(node.parent);
}
else {
// 非叶子置换
if (node.left && !node.right) {
// 和左节点置换
node = this._swapNode(node, node.left);
}
else if (!node.left && node.right) {
// 和右节点置换
node = this._swapNode(node, node.right);
}
else {
// 双节点 寻找后继节点
let _swapNode = this._successor(node);
node = this._swapNode(node, _swapNode);
}
this._onRemove(node);
}
return true;
}
/**
* 修复序号
* @param node
* @returns
*/
_onRepairIndex(node) {
if (!node.parent) {
return;
}
if (node.isLeftChild()) {
node.parent.index--;
}
this._onRepairIndex(node.parent);
}
/**
* 修复节点, 调整平衡
* @param node
*/
_onRepairNode(node) {
if (node.isRoot() || node.isRed()) {
return;
}
let parent = node.parent;
let brother = node.getBrother();
if (brother.isBlack()) {
// 兄弟节点为黑色
if (node.isLeftChild()) {
// 左节点
if (brother.right && !brother.left) {
// 只有右节点
// 左旋转父节点
this._rotateLeft(parent);
brother.setColor(parent.color);
brother.right.setBlack();
parent.setBlack();
}
else if (!brother.right && brother.left) {
brother.left.setBlack();
brother.setRed();
this._rotateRight(brother);
this._onRepairNode(node);
}
else if (brother.left && brother.right) {
brother.setColor(parent.color);
brother.right.setBlack();
parent.setBlack();
this._rotateLeft(parent);
}
else if (!brother.left && !brother.right) {
brother.setRed();
this._onRepairNode(parent);
}
}
else {
// 右节点
if (brother.left && !brother.right) {
brother.setColor(parent.color);
brother.left.setBlack();
parent.setBlack();
this._rotateRight(parent);
}
else if (!brother.left && brother.right) {
brother.right.setBlack();
brother.setRed();
this._rotateLeft(brother);
this._onRepairNode(node);
}
else if (brother.left && brother.right) {
brother.setColor(parent.color);
brother.left.setBlack();
parent.setBlack();
this._rotateRight(parent);
}
else if (!brother.left && !brother.right) {
brother.setRed();
this._onRepairNode(parent);
}
}
}
else {
// 兄弟节点为红色
if (node.isLeftChild()) {
brother.setBlack();
brother.left.setRed();
this._rotateLeft(parent);
}
else {
brother.setBlack();
brother.right.setRed();
this._rotateRight(parent);
}
}
}
/**
* 调整树 使之保持平衡
* @param node 节点
*/
_onTuneUp(node) {
let parent = node.parent;
if (!parent) {
// 根节点
node.setBlack();
return;
}
if (parent.isRed()) {
let grandparent = parent.parent;
let uncle = parent.getBrother();
if (uncle && uncle.isRed()) {
uncle.setBlack();
parent.setBlack();
grandparent.setRed();
this._onTuneUp(grandparent);
}
else if (!uncle || uncle.isBlack()) {
let tmp = grandparent.parent;
let isLeft = grandparent.isLeftChild();
if (parent.isLeftChild() && node.isLeftChild()) {
// 左左
grandparent.parent = parent;
grandparent.left = parent.right;
grandparent.index = (parent.right ? parent.right.index : 0) + 1;
if (parent.right) {
parent.right.parent = grandparent;
}
grandparent.setRed();
parent.right = grandparent;
parent.setBlack();
if (!tmp) {
this._root = parent;
parent.parent = null;
}
else {
if (isLeft) {
tmp.left = parent;
}
else {
tmp.right = parent;
}
parent.parent = tmp;
}
}
else if (parent.isLeftChild() && node.isRightChild()) {
// 左右
grandparent.left = node;
node.parent = grandparent;
parent.right = node.left;
if (node.left) {
node.left.parent = parent;
}
parent.parent = node;
node.left = parent;
node.index += parent.index;
this._onTuneUp(parent);
}
else if (parent.isRightChild() && node.isRightChild()) {
// 右右
grandparent.parent = parent;
grandparent.right = parent.left;
if (parent.left) {
parent.left.parent = grandparent;
}
grandparent.setRed();
parent.index += grandparent.index;
parent.left = grandparent;
parent.setBlack();
if (!tmp) {
parent.parent = null;
this._root = parent;
}
else {
if (isLeft) {
tmp.left = parent;
}
else {
tmp.right = parent;
}
parent.parent = tmp;
}
}
else if (parent.isRightChild() && node.isLeftChild()) {
// 右左
grandparent.right = node;
node.parent = grandparent;
parent.left = node.right;
if (node.right) {
node.right.parent = parent;
}
parent.parent = node;
parent.index -= node.index;
node.right = parent;
this._onTuneUp(parent);
}
}
}
}
/**
* 寻找后继节点
* @param node
*/
_successor(node) {
if (node == null) {
return null;
}
if (null != node.right) { // 获取 后继节点
let p = node.right;
while (null != p.left) {
p = p.left;
}
return p;
}
else {
let p = node.parent;
let ch = node;
while (p != null && ch == p.right) {
ch = p;
p = p.parent;
}
return p;
}
}
/**
* 左旋转
* @param node
*/
_rotateLeft(node) {
let isLeft = node.isLeftChild();
let parent = node.parent;
let right = node.right;
// 更新index
right.index += node.index;
node.right = right.left;
if (right.left) {
right.left.parent = node;
}
// 链接
right.left = node;
node.parent = right;
right.parent = parent;
if (parent) {
if (isLeft) {
parent.left = right;
}
else {
parent.right = right;
}
}
else {
this._root = right;
}
}
/**
* 左旋转
* @param node
*/
_rotateRight(node) {
let isLeft = node.isLeftChild();
let parent = node.parent;
let left = node.left;
// 更新index
// left.index += node.index;
node.index = (left.right ? left.right.index : 0) + 1;
node.left = left.right;
if (left.right) {
left.right.parent = node;
}
// 链接
left.right = node;
node.parent = left;
left.parent = parent;
if (parent) {
if (isLeft) {
parent.left = left;
}
else {
parent.right = left;
}
}
else {
this._root = left;
}
}
/**
* 交换节点位置 简单做法为值交换 这里采用节点交换 (弃用)
* @param nodeFirst
* @param nodeSecond
*/
__swapNode(nodeFirst, nodeSecond) {
let firstParent = nodeFirst.parent;
let firstLeft = nodeFirst.left;
let firstRight = nodeFirst.right;
let firstIsLeft = nodeFirst.isLeftChild();
let secondParent = nodeSecond.parent;
let secondLeft = nodeSecond.left;
let secondRight = nodeSecond.right;
let secondIsLeft = nodeSecond.isLeftChild();
// TODO 交换的节点为父子关系 需要处理
// 重定向first node
nodeFirst.parent = secondParent;
if (secondParent) {
if (secondIsLeft) {
secondParent.left = nodeFirst;
}
else {
secondParent.right = nodeFirst;
}
}
nodeFirst.left = secondLeft;
if (secondLeft) {
secondLeft.parent = nodeFirst;
}
nodeFirst.right = secondRight;
if (secondRight) {
secondRight.parent = nodeFirst;
}
// 重定向second node
nodeSecond.parent = firstParent;
if (firstParent) {
if (firstIsLeft) {
firstParent.left = nodeFirst;
}
else {
secondParent.right = nodeFirst;
}
}
nodeSecond.left = firstLeft;
if (firstLeft) {
firstLeft.parent = nodeSecond;
}
nodeSecond.right = firstRight;
if (firstRight) {
firstRight.parent = nodeSecond;
}
}
/**
* 交换节点位置 简单值交换
* @param nodeFirst
* @param nodeSecond
*/
_swapNode(nodeFirst, nodeSecond) {
let keyFirst = nodeFirst.key;
let scoreFirst = nodeFirst.score;
let keySecond = nodeSecond.key;
let scoreSecond = nodeSecond.score;
nodeFirst.key = keySecond;
nodeFirst.score = scoreSecond;
nodeSecond.key = keyFirst;
nodeSecond.score = scoreFirst;
this._hash.set(nodeFirst.key, nodeFirst);
this._hash.set(nodeSecond.key, nodeSecond);
return nodeSecond;
}
/**
* 比较器
* @param e 当前
* @param target 目标
* @returns
*/
_compare(e, target) {
return e.score < target.score;
}
/**
* 获取序号
* @param prev
* @param node
* @param index
* @returns
*/
_onGetIndex(prev, node, index) {
if (!prev) {
return -1;
}
if (node == prev) {
return prev.index + index;
}
if (this._compare(node, prev)) {
return this._onGetIndex(prev.left, node, index);
}
else {
return this._onGetIndex(prev.right, node, index + prev.index);
}
}
/**
* 寻找指定分数的前驱节点
* @param prev
* @param min
* @returns
*/
_findScoreStartNode(prev, min) {
if (!prev) {
return null;
}
if (min <= prev.score) {
if (!prev.left) {
return prev;
}
else {
let res = this._findScoreStartNode(prev.left, min);
if (res) {
return res;
}
return prev;
}
}
else {
if (!prev.right) {
return null;
}
else {
return this._findScoreStartNode(prev.right, min);
}
}
}
_LDR_selectScoreRange(prev, list, min, max) {
if (!prev) {
return;
}
if (prev.score < min) {
this._LDR_selectScoreRange(prev.parent, list, min, max);
return;
}
// 先解决此节点下的问元素
if (prev.score > max) {
return;
}
list.push([prev.key, prev.score]);
// 解决右子树
this._LDR_SCORE(prev.right, list, max);
this._LDR_selectScoreRange(prev.parent, list, min, max);
}
_LDR_SCORE(prev, list, max) {
if (!prev) {
return;
}
this._LDR_SCORE(prev.left, list, max);
if (prev.score > max) {
return;
}
list.push([prev.key, prev.score]);
this._LDR_SCORE(prev.right, list, max);
}
_findIndexStartNode(prev, minI) {
if (!prev) {
return null;
}
if (prev.index == minI) {
return prev;
}
else if (prev.index < minI) {
minI -= prev.index;
return this._findIndexStartNode(prev.right, minI);
}
return this._findIndexStartNode(prev.left, minI);
}
_LDR_selectIndexRange(prev, list, count, prevI, minI, maxI) {
if (!prev) {
return;
}
// 已经满足筛选
if (list.length >= count) {
return;
}
let nextPrevI;
// 计算父节点 prevI
if (prev.parent) {
if (prev.isLeftChild()) {
nextPrevI = prevI + (prev.parent.index - prev.index);
}
else {
nextPrevI = prevI - prev.index;
}
}
if (prevI < minI) {
if (prev.parent) {
this._LDR_selectIndexRange(prev.parent, list, count, nextPrevI, minI, maxI);
}
return;
}
list.push([prev.key, prev.score]);
// 解决右子树
this._LDR_INDEX(prev.right, list, count);
if (prev.parent) {
this._LDR_selectIndexRange(prev.parent, list, count, nextPrevI, minI, maxI);
}
}
_LDR_INDEX(prev, list, count) {
if (!prev) {
return;
}
this._LDR_INDEX(prev.left, list, count);
// 满足筛选
if (list.length >= count) {
return;
}
list.push([prev.key, prev.score]);
this._LDR_INDEX(prev.right, list, count);
}
}
exports.RankTree = RankTree;
//# sourceMappingURL=rank.js.map