Tims-Chat/files_wcf/js/Bastelstu.be/Chat/DataStructure/RedBlackTree/Node.js

137 lines
3.4 KiB
JavaScript
Raw Normal View History

2018-08-16 22:30:59 +00:00
/*
* Copyright (c) 2010-2018 Tim Düsterhus.
*
* Use of this software is governed by the Business Source License
* included in the LICENSE file.
*
2020-11-01 16:09:27 +00:00
* Change Date: 2024-11-01
2018-08-16 22:30:59 +00:00
*
* On the date above, in accordance with the Business Source
* License, use of this software will be governed by version 2
* or later of the General Public License.
*/
define([ ], function () {
"use strict";
class Node {
constructor(value) {
this.value = value
this._left = undefined
this._right = undefined
this.parent = undefined
this.color = 'RED'
}
get left() {
return this._left
}
set left(node) {
if (this._left) this._left.parent = undefined
if (node !== undefined) {
if (node.parent !== undefined) {
if (node.isLeftChild) node.parent.left = undefined
else if (node.isRightChild) node.parent.right = undefined
else throw new Error('Unreachable')
}
node.parent = this
}
this._left = node
}
get right() {
return this._right
}
set right(node) {
if (this._right) this._right.parent = undefined
if (node !== undefined) {
if (node.parent !== undefined) {
if (node.isLeftChild) node.parent.left = undefined
else if (node.isRightChild) node.parent.right = undefined
else throw new Error('Unreachable')
}
node.parent = this
}
this._right = node
}
get isRoot() {
return this.parent === undefined
}
get isLeaf() {
return this.left === undefined && this.right === undefined
}
get isLeftChild() {
if (this.parent === undefined) return false
return this.parent.left === this
}
get isRightChild() {
if (this.parent === undefined) return false
return this.parent.right === this
}
get grandparent() {
if (this.parent === undefined) return undefined
return this.parent.parent
}
get sibling() {
if (this.parent === undefined) return undefined
if (this.isLeftChild) return this.parent.right
return this.parent.left
}
get uncle() {
if (this.parent === undefined) return undefined
return this.parent.sibling
}
search(value) {
if (value === this.value) return [ 'IS', this ]
if (value < this.value) {
if (this.left !== undefined) return this.left.search(value)
return [ 'LEFT', this ]
}
if (value > this.value) {
if (this.right !== undefined) return this.right.search(value)
return [ 'RIGHT', this ]
}
throw new Error('Unreachable')
}
print(depth = 0) {
console.log(" ".repeat(depth) + `${this.value}: ${this.color} (Parent: ${this.parent ? this.parent.value : '-'})`)
if (this.left) this.left.print(depth + 1)
else console.log(" ".repeat(depth + 1) + '-')
if (this.right) this.right.print(depth + 1)
else console.log(" ".repeat(depth + 1) + '-')
}
check() {
if (this.left && this.left.value >= this.value) throw new Error('Invalid' + this.value);
if (this.right && this.right.value <= this.value) throw new Error('Invalid' + this.value);
if (this.color === 'RED' && ((this.left && this.left.color !== 'BLACK') || (this.right && this.right.color !== 'BLACK'))) throw new Error('Invalid' + this.value);
let leftBlacks = 1, rightBlacks = 1
if (this.left) {
leftBlacks = this.left.check()
}
if (this.right) {
rightBlacks = this.right.check()
}
if (leftBlacks !== rightBlacks) throw new Error('Invalid' + this.value);
if (this.color === 'BLACK') return leftBlacks + 1
return leftBlacks
}
}
return Node
});