172 lines
3.1 KiB
JavaScript
172 lines
3.1 KiB
JavaScript
|
const LEAF = 0;
|
||
|
const UNARY = 1;
|
||
|
const BINARY = 2;
|
||
|
|
||
|
function nodeHeight(node) {
|
||
|
if (node == null) {
|
||
|
return -1;
|
||
|
}
|
||
|
return 1 + Math.max(nodeHeight(node.left), nodeHeight(node.right));
|
||
|
}
|
||
|
|
||
|
function nodeRank(node) {
|
||
|
if (node == null) {
|
||
|
return -1;
|
||
|
}
|
||
|
return node.rank;
|
||
|
}
|
||
|
|
||
|
function nodeDifference(node, parent) {
|
||
|
if (parent === undefined) {
|
||
|
parent = node != null ? node.parent : null;
|
||
|
}
|
||
|
return nodeRank(parent) - nodeRank(node);
|
||
|
}
|
||
|
|
||
|
function nodeDifferences(node) {
|
||
|
let r = nodeRank(node);
|
||
|
let left = null;
|
||
|
let right = null;
|
||
|
|
||
|
if (node != null) {
|
||
|
left = node.left;
|
||
|
right = node.right;
|
||
|
}
|
||
|
|
||
|
return [r - nodeRank(left), r - nodeRank(right)];
|
||
|
}
|
||
|
|
||
|
function rotateRight(x) {
|
||
|
let parent = x.parent;
|
||
|
let y = x.left;
|
||
|
// let z = x.right;
|
||
|
|
||
|
if (parent != null) {
|
||
|
if (parent.left === x) {
|
||
|
parent.left = y;
|
||
|
} else {
|
||
|
parent.right = y;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
x.left = y.right;
|
||
|
if (x.left != null) {
|
||
|
x.left.parent = x;
|
||
|
}
|
||
|
|
||
|
y.right = x;
|
||
|
x.parent = y;
|
||
|
y.parent = parent;
|
||
|
|
||
|
return y;
|
||
|
}
|
||
|
|
||
|
function rotateLeft(x) {
|
||
|
let parent = x.parent;
|
||
|
// let y = x.left;
|
||
|
let z = x.right;
|
||
|
|
||
|
if (parent != null) {
|
||
|
if (parent.left === x) {
|
||
|
parent.left = z;
|
||
|
} else {
|
||
|
parent.right = z;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
x.right = z.left;
|
||
|
if (x.right != null) {
|
||
|
x.right.parent = x;
|
||
|
}
|
||
|
|
||
|
z.left = x;
|
||
|
x.parent = z;
|
||
|
z.parent = parent;
|
||
|
|
||
|
return z;
|
||
|
}
|
||
|
|
||
|
function findParentNode(value, node, missing) {
|
||
|
if (missing === undefined) {
|
||
|
missing = true;
|
||
|
}
|
||
|
|
||
|
newNode = node
|
||
|
|
||
|
while (newNode && (missing || newNode.value != value)) {
|
||
|
node = newNode;
|
||
|
if (value < node.value) {
|
||
|
newNode = node.left;
|
||
|
} else if (node.value < value) {
|
||
|
newNode = node.right;
|
||
|
} else {
|
||
|
// same value
|
||
|
return null;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
return node;
|
||
|
}
|
||
|
|
||
|
function nodeSearch(value, node) {
|
||
|
while (node && node.value != value) {
|
||
|
node = (value < node.value) ? node.left : node.right;
|
||
|
}
|
||
|
|
||
|
return node;
|
||
|
}
|
||
|
|
||
|
function nodeMinimum(node) {
|
||
|
while (node.left != null) {
|
||
|
node = node.left;
|
||
|
}
|
||
|
return node;
|
||
|
}
|
||
|
|
||
|
function nodeMaximum(node) {
|
||
|
while (node.right != null) {
|
||
|
node = node.right;
|
||
|
}
|
||
|
return node;
|
||
|
}
|
||
|
|
||
|
class Node {
|
||
|
constructor(value, left, right, parent) {
|
||
|
this.value = value;
|
||
|
this.rank = 0;
|
||
|
|
||
|
this.parent = parent || null;
|
||
|
this.left = left || null;
|
||
|
this.right = right || null;
|
||
|
}
|
||
|
|
||
|
type() {
|
||
|
if (this.left != null && this.right != null) {
|
||
|
return BINARY;
|
||
|
}
|
||
|
|
||
|
if (this.left != null || this.right != null) {
|
||
|
return UNARY;
|
||
|
}
|
||
|
|
||
|
return LEAF;
|
||
|
}
|
||
|
|
||
|
serialize() {
|
||
|
return `Node(value=${this.value}, rank = ${this.rank}, left=${this.left}, right=${this.right}, parent=${this.parent})`;
|
||
|
}
|
||
|
|
||
|
toString() {
|
||
|
return `Node(value=${this.value}, rank=${this.rank})`;
|
||
|
}
|
||
|
|
||
|
promote() {
|
||
|
this.rank++;
|
||
|
return this;
|
||
|
}
|
||
|
|
||
|
demote() {
|
||
|
this.rank--;
|
||
|
return this;
|
||
|
}
|
||
|
}
|