Compare commits
6 commits
Author | SHA1 | Date | |
---|---|---|---|
56359109a9 | |||
ea9a1d785a | |||
5388f21f04 | |||
2bc43652d0 | |||
dce3e3c11c | |||
df787476ac |
8 changed files with 260 additions and 62 deletions
21
.gitlab-ci.yml
Normal file
21
.gitlab-ci.yml
Normal file
|
@ -0,0 +1,21 @@
|
||||||
|
pages:
|
||||||
|
script:
|
||||||
|
- mkdir .public
|
||||||
|
- cp -r * .public
|
||||||
|
- mv .public public
|
||||||
|
artifacts:
|
||||||
|
paths:
|
||||||
|
- public
|
||||||
|
only:
|
||||||
|
- main
|
||||||
|
|
||||||
|
pre-commit:
|
||||||
|
variables:
|
||||||
|
PRE_COMMIT_HOME: ${CI_PROJECT_DIR}/.cache/pre-commit
|
||||||
|
cache:
|
||||||
|
paths:
|
||||||
|
- ${PRE_COMMIT_HOME}
|
||||||
|
image: registry.gitlab.com/yesolutions/docker-pre-commit
|
||||||
|
script:
|
||||||
|
- pip install pre-commit
|
||||||
|
- pre-commit run --all-files
|
55
avl.js
55
avl.js
|
@ -33,30 +33,24 @@ class AVLTree extends RankedTree {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
fix0Child(x, y, z, rotatingAroundRoot, rotateLeft, rotateRight) {
|
fix0Child(x, y, z, rotateLeft, rotateRight) {
|
||||||
let newRoot = x.parent;
|
let newRoot = x.parent;
|
||||||
|
|
||||||
if (!y || nodeDifference(y) == 2) {
|
if (!y || nodeDifference(y) == 2) {
|
||||||
newRoot = rotateRight(z);
|
newRoot = rotateRight(this, z);
|
||||||
if (rotatingAroundRoot) {
|
|
||||||
this.root = newRoot;
|
|
||||||
}
|
|
||||||
this.record("Fixing 0-child by single rotation: by z", z, newRoot);
|
this.record("Fixing 0-child by single rotation: by z", z, newRoot);
|
||||||
|
|
||||||
z.demote();
|
z.demote();
|
||||||
this.record("Fixing 0-child by single rotation: demoting z", z);
|
this.record("Fixing 0-child by single rotation: demoting z", z);
|
||||||
} else if (nodeDifference(y) == 1) {
|
} else if (nodeDifference(y) == 1) {
|
||||||
let intermediateRoot = rotateLeft(x);
|
let intermediateRoot = rotateLeft(this, x);
|
||||||
this.record(
|
this.record(
|
||||||
"Fixing 0-child by double-rotation: first rotation by x",
|
"Fixing 0-child by double-rotation: first rotation by x",
|
||||||
x,
|
x,
|
||||||
intermediateRoot
|
intermediateRoot
|
||||||
);
|
);
|
||||||
|
|
||||||
newRoot = rotateRight(z);
|
newRoot = rotateRight(this, z);
|
||||||
if (rotatingAroundRoot) {
|
|
||||||
this.root = newRoot;
|
|
||||||
}
|
|
||||||
this.record(
|
this.record(
|
||||||
"Fixing 0-child by double-rotation: second rotation by z",
|
"Fixing 0-child by double-rotation: second rotation by z",
|
||||||
z,
|
z,
|
||||||
|
@ -91,8 +85,6 @@ class AVLTree extends RankedTree {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
let rotatingAroundRoot = x.parent.parent == null;
|
|
||||||
|
|
||||||
let rankDifference = nodeDifference(x);
|
let rankDifference = nodeDifference(x);
|
||||||
if (rankDifference != 0) {
|
if (rankDifference != 0) {
|
||||||
return;
|
return;
|
||||||
|
@ -101,49 +93,32 @@ class AVLTree extends RankedTree {
|
||||||
let xParent = x.parent;
|
let xParent = x.parent;
|
||||||
|
|
||||||
if (rankDifference == 0 && x.parent.left === x) {
|
if (rankDifference == 0 && x.parent.left === x) {
|
||||||
this.fix0Child(
|
this.fix0Child(x, x.right, xParent, rotateLeft, rotateRight);
|
||||||
x,
|
|
||||||
x.right,
|
|
||||||
xParent,
|
|
||||||
rotatingAroundRoot,
|
|
||||||
rotateLeft,
|
|
||||||
rotateRight
|
|
||||||
);
|
|
||||||
} else if (rankDifference == 0 && x.parent.right === x) {
|
} else if (rankDifference == 0 && x.parent.right === x) {
|
||||||
this.fix0Child(
|
this.fix0Child(x, x.left, xParent, rotateRight, rotateLeft);
|
||||||
x,
|
|
||||||
x.left,
|
|
||||||
xParent,
|
|
||||||
rotatingAroundRoot,
|
|
||||||
rotateRight,
|
|
||||||
rotateLeft
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
deleteRotate(x, y, leaning, rotatingAroundRoot, rotateLeft, rotateRight) {
|
deleteRotate(x, y, leaning, rotateLeft, rotateRight) {
|
||||||
let newRoot = x;
|
let newRoot = x;
|
||||||
|
|
||||||
let factor = balanceFactor(y);
|
let factor = balanceFactor(y);
|
||||||
switch (factor) {
|
switch (factor) {
|
||||||
case 0:
|
case 0:
|
||||||
case leaning:
|
case leaning:
|
||||||
newRoot = rotateLeft(x);
|
newRoot = rotateLeft(this, x);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
let intermediateRoot = rotateRight(y);
|
let intermediateRoot = rotateRight(this, y);
|
||||||
this.record(
|
this.record(
|
||||||
"AVL deletion, fixing by double-rotation: by y",
|
"AVL deletion, fixing by double-rotation: by y",
|
||||||
y,
|
y,
|
||||||
intermediateRoot
|
intermediateRoot
|
||||||
);
|
);
|
||||||
|
|
||||||
newRoot = rotateLeft(x);
|
newRoot = rotateLeft(this, x);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (rotatingAroundRoot) {
|
|
||||||
this.root = newRoot;
|
|
||||||
}
|
|
||||||
this.record("AVL deletion, fixing by rotation by x", x, newRoot);
|
this.record("AVL deletion, fixing by rotation by x", x, newRoot);
|
||||||
|
|
||||||
[newRoot.left, newRoot.right, newRoot]
|
[newRoot.left, newRoot.right, newRoot]
|
||||||
|
@ -172,7 +147,6 @@ class AVLTree extends RankedTree {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
let rotatingAroundRoot = x.parent == null;
|
|
||||||
let [z, leaning, toLeft, toRight] = [
|
let [z, leaning, toLeft, toRight] = [
|
||||||
x.left,
|
x.left,
|
||||||
-1,
|
-1,
|
||||||
|
@ -188,14 +162,7 @@ class AVLTree extends RankedTree {
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
return this.deleteRotate(
|
return this.deleteRotate(x, z, leaning, toLeft, toRight);
|
||||||
x,
|
|
||||||
z,
|
|
||||||
leaning,
|
|
||||||
rotatingAroundRoot,
|
|
||||||
toLeft,
|
|
||||||
toRight
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
deleteRebalance(node, parent) {
|
deleteRebalance(node, parent) {
|
||||||
|
|
|
@ -148,6 +148,18 @@
|
||||||
<label class="btn btn-outline-primary" for="lRavlTreeBtn"
|
<label class="btn btn-outline-primary" for="lRavlTreeBtn"
|
||||||
>rAVL</label
|
>rAVL</label
|
||||||
>
|
>
|
||||||
|
|
||||||
|
<input
|
||||||
|
type="radio"
|
||||||
|
class="btn-check"
|
||||||
|
name="leftTreeSelection"
|
||||||
|
id="lRbTreeBtn"
|
||||||
|
autocomplete="off"
|
||||||
|
onclick="switchTree(RBTree, 'left')"
|
||||||
|
/>
|
||||||
|
<label class="btn btn-outline-primary" for="lRbTreeBtn"
|
||||||
|
>Red-Black</label
|
||||||
|
>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -190,6 +202,18 @@
|
||||||
<label class="btn btn-outline-primary" for="rRavlTreeBtn"
|
<label class="btn btn-outline-primary" for="rRavlTreeBtn"
|
||||||
>rAVL</label
|
>rAVL</label
|
||||||
>
|
>
|
||||||
|
|
||||||
|
<input
|
||||||
|
type="radio"
|
||||||
|
class="btn-check"
|
||||||
|
name="rightTreeSelection"
|
||||||
|
id="rRbTreeBtn"
|
||||||
|
autocomplete="off"
|
||||||
|
onclick="switchTree(RBTree, 'right')"
|
||||||
|
/>
|
||||||
|
<label class="btn btn-outline-primary" for="rRbTreeBtn"
|
||||||
|
>Red-Black</label
|
||||||
|
>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -211,6 +235,7 @@
|
||||||
<script src="avl.js"></script>
|
<script src="avl.js"></script>
|
||||||
<script src="wavl.js"></script>
|
<script src="wavl.js"></script>
|
||||||
<script src="ravl.js"></script>
|
<script src="ravl.js"></script>
|
||||||
|
<script src="rbt.js"></script>
|
||||||
|
|
||||||
<script src="recorder.js"></script>
|
<script src="recorder.js"></script>
|
||||||
|
|
||||||
|
|
13
index.html
13
index.html
|
@ -115,6 +115,18 @@
|
||||||
<label class="btn btn-outline-primary" for="ravlTreeBtn"
|
<label class="btn btn-outline-primary" for="ravlTreeBtn"
|
||||||
>rAVL</label
|
>rAVL</label
|
||||||
>
|
>
|
||||||
|
|
||||||
|
<input
|
||||||
|
type="radio"
|
||||||
|
class="btn-check"
|
||||||
|
name="treeSelection"
|
||||||
|
id="rbTreeBtn"
|
||||||
|
autocomplete="off"
|
||||||
|
onclick="switchTree(RBTree)"
|
||||||
|
/>
|
||||||
|
<label class="btn btn-outline-primary" for="rbTreeBtn"
|
||||||
|
>Red-Black</label
|
||||||
|
>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -186,6 +198,7 @@
|
||||||
<script src="avl.js"></script>
|
<script src="avl.js"></script>
|
||||||
<script src="wavl.js"></script>
|
<script src="wavl.js"></script>
|
||||||
<script src="ravl.js"></script>
|
<script src="ravl.js"></script>
|
||||||
|
<script src="rbt.js"></script>
|
||||||
|
|
||||||
<script src="recorder.js"></script>
|
<script src="recorder.js"></script>
|
||||||
|
|
||||||
|
|
8
node.js
8
node.js
|
@ -36,7 +36,7 @@ function nodeDifferences(node) {
|
||||||
return [r - nodeRank(left), r - nodeRank(right)];
|
return [r - nodeRank(left), r - nodeRank(right)];
|
||||||
}
|
}
|
||||||
|
|
||||||
function rotateRight(x) {
|
function rotateRight(t, x) {
|
||||||
let parent = x.parent;
|
let parent = x.parent;
|
||||||
let y = x.left;
|
let y = x.left;
|
||||||
// let z = x.right;
|
// let z = x.right;
|
||||||
|
@ -47,6 +47,8 @@ function rotateRight(x) {
|
||||||
} else {
|
} else {
|
||||||
parent.right = y;
|
parent.right = y;
|
||||||
}
|
}
|
||||||
|
} else if (t) {
|
||||||
|
t.root = y;
|
||||||
}
|
}
|
||||||
|
|
||||||
x.left = y.right;
|
x.left = y.right;
|
||||||
|
@ -61,7 +63,7 @@ function rotateRight(x) {
|
||||||
return y;
|
return y;
|
||||||
}
|
}
|
||||||
|
|
||||||
function rotateLeft(x) {
|
function rotateLeft(t, x) {
|
||||||
let parent = x.parent;
|
let parent = x.parent;
|
||||||
// let y = x.left;
|
// let y = x.left;
|
||||||
let z = x.right;
|
let z = x.right;
|
||||||
|
@ -72,6 +74,8 @@ function rotateLeft(x) {
|
||||||
} else {
|
} else {
|
||||||
parent.right = z;
|
parent.right = z;
|
||||||
}
|
}
|
||||||
|
} else if (t) {
|
||||||
|
t.root = z;
|
||||||
}
|
}
|
||||||
|
|
||||||
x.right = z.left;
|
x.right = z.left;
|
||||||
|
|
|
@ -37,10 +37,12 @@ class RankedTree {
|
||||||
|
|
||||||
edges.forEach((vertices) => {
|
edges.forEach((vertices) => {
|
||||||
let [u, v] = vertices;
|
let [u, v] = vertices;
|
||||||
|
let diff = nodeDifference(v);
|
||||||
|
|
||||||
result.push(
|
result.push(
|
||||||
`\t"Node(${u.value})" -> "Node(${
|
`\t"Node(${u.value})" -> "Node(${
|
||||||
v.value
|
v.value
|
||||||
})" [label="${nodeDifference(v)}"];\n`
|
})" [label="${diff}"${this.styleEdge(diff)}];\n`
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -176,4 +178,8 @@ class RankedTree {
|
||||||
deleteRebalance(node, parent) {
|
deleteRebalance(node, parent) {
|
||||||
throw "not implemented!";
|
throw "not implemented!";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
styleEdge(rankDifference) {
|
||||||
|
return "";
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
173
rbt.js
Normal file
173
rbt.js
Normal file
|
@ -0,0 +1,173 @@
|
||||||
|
const RED = 0;
|
||||||
|
const BLACK = 1;
|
||||||
|
|
||||||
|
function isDoubleBlack(x) {
|
||||||
|
return x && nodeDifferences(x).indexOf(2) != -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
class RBTree extends RankedTree {
|
||||||
|
isCorrectNode(node, recursive) {
|
||||||
|
if (!node) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
let [left, right] = nodeDifferences(node);
|
||||||
|
if ([RED, BLACK].indexOf(left) == -1) {
|
||||||
|
// left subtree has invalid difference
|
||||||
|
return false;
|
||||||
|
} else if ([RED, BLACK].indexOf(right) == -1) {
|
||||||
|
// right subtree has invalid difference
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (nodeDifference(node) == RED && (left == RED || right == RED)) {
|
||||||
|
// two consecutive red nodes
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
recursive = recursive ?? true;
|
||||||
|
return (
|
||||||
|
!recursive ||
|
||||||
|
(this.isCorrectNode(node.left) && this.isCorrectNode(node.right))
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
insertRebalanceStep(z, y, rightChild, rotateLeft, rotateRight) {
|
||||||
|
let [p, pp] = [z.parent, z.parent.parent];
|
||||||
|
|
||||||
|
if (y && nodeDifference(y) == RED) {
|
||||||
|
// Case 1
|
||||||
|
// ======
|
||||||
|
// z’s uncle y is red
|
||||||
|
pp.rank++;
|
||||||
|
this.record("Insertion case #1: recoloring uncle", pp);
|
||||||
|
z = pp;
|
||||||
|
} else if (z === rightChild) {
|
||||||
|
// Case 2
|
||||||
|
// ======
|
||||||
|
// z’s uncle y is black and z is a right child
|
||||||
|
z = p;
|
||||||
|
rotateLeft(this, p);
|
||||||
|
this.record("Insertion case #2: rotating by parent");
|
||||||
|
} else {
|
||||||
|
// Case 3
|
||||||
|
// ======
|
||||||
|
// z’s uncle y is black and z is a left child
|
||||||
|
rotateRight(this, pp);
|
||||||
|
this.record("Insertion case #3: rotating by grandparent");
|
||||||
|
}
|
||||||
|
|
||||||
|
return z;
|
||||||
|
}
|
||||||
|
|
||||||
|
insertRebalance(z) {
|
||||||
|
while (z.parent && nodeDifference(z.parent) == RED) {
|
||||||
|
let [p, pp] = [z.parent, z.parent.parent];
|
||||||
|
|
||||||
|
if (p === pp.left) {
|
||||||
|
z = this.insertRebalanceStep(
|
||||||
|
z,
|
||||||
|
pp.right,
|
||||||
|
p.right,
|
||||||
|
rotateLeft,
|
||||||
|
rotateRight
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
z = this.insertRebalanceStep(
|
||||||
|
z,
|
||||||
|
pp.left,
|
||||||
|
p.left,
|
||||||
|
rotateRight,
|
||||||
|
rotateLeft
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
deleteRebalanceStep(x, w, parent, right, rotateLeft, rotateRight) {
|
||||||
|
if (nodeDifference(w) == RED) {
|
||||||
|
// Case 1
|
||||||
|
// ======
|
||||||
|
// x’s sibling w is red
|
||||||
|
rotateLeft(this, parent);
|
||||||
|
this.record("Deletion case #1: rotating by parent", parent);
|
||||||
|
w = right(parent);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (nodeDifferences(w).equals([BLACK, BLACK])) {
|
||||||
|
// Case 2
|
||||||
|
// ======
|
||||||
|
// x’s sibling w is black, and both of w’s children are black
|
||||||
|
parent.rank--;
|
||||||
|
this.record("Deletion case #2: recoloring sibling", w);
|
||||||
|
x = parent;
|
||||||
|
} else {
|
||||||
|
// Case 3
|
||||||
|
// ======
|
||||||
|
// x’s sibling w is black,
|
||||||
|
// w’s left child is red, and w’s right child is black
|
||||||
|
if (nodeDifference(right(w), w) == BLACK) {
|
||||||
|
rotateRight(this, w);
|
||||||
|
this.record("Deletion case #3: rotating by w", w);
|
||||||
|
w = right(parent);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Case 4
|
||||||
|
// ======
|
||||||
|
// x’s sibling w is black, and w’s right child is red
|
||||||
|
parent.rank--;
|
||||||
|
this.record(
|
||||||
|
"Deletion case #4: moving double black to parent",
|
||||||
|
parent
|
||||||
|
);
|
||||||
|
w.rank++;
|
||||||
|
this.record("Deletion case #4: coloring w's child", w);
|
||||||
|
rotateLeft(this, parent);
|
||||||
|
this.record("Deletion case #4: rotating by parent", parent);
|
||||||
|
|
||||||
|
x = this.root;
|
||||||
|
}
|
||||||
|
|
||||||
|
return [x, x ? x.parent : null];
|
||||||
|
}
|
||||||
|
|
||||||
|
deleteRebalance(node, parent) {
|
||||||
|
if (!node && !parent) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
while (node !== this.root && isDoubleBlack(parent)) {
|
||||||
|
if (node === parent.left) {
|
||||||
|
[node, parent] = this.deleteRebalanceStep(
|
||||||
|
node,
|
||||||
|
parent.right,
|
||||||
|
parent,
|
||||||
|
(x) => x.right,
|
||||||
|
rotateLeft,
|
||||||
|
rotateRight
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
[node, parent] = this.deleteRebalanceStep(
|
||||||
|
node,
|
||||||
|
parent.left,
|
||||||
|
parent,
|
||||||
|
(x) => x.left,
|
||||||
|
rotateRight,
|
||||||
|
rotateLeft
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
styleEdge(rankDifference) {
|
||||||
|
switch (rankDifference) {
|
||||||
|
case 2:
|
||||||
|
return " penwidth=2";
|
||||||
|
case 0:
|
||||||
|
return ', color="red"';
|
||||||
|
case 1:
|
||||||
|
default:
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
19
wavl.js
19
wavl.js
|
@ -21,7 +21,7 @@ class WAVLTree extends AVLTree {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
fixDelete(x, y, z, reversed, rotatingAroundRoot, rotateLeft, rotateRight) {
|
fixDelete(x, y, z, reversed, rotateLeft, rotateRight) {
|
||||||
let newRoot = x;
|
let newRoot = x;
|
||||||
let [v, w] = [y.left, y.right];
|
let [v, w] = [y.left, y.right];
|
||||||
|
|
||||||
|
@ -30,13 +30,9 @@ class WAVLTree extends AVLTree {
|
||||||
}
|
}
|
||||||
|
|
||||||
let wDiff = nodeDifference(w, y);
|
let wDiff = nodeDifference(w, y);
|
||||||
|
|
||||||
if (wDiff == 1 && y.parent) {
|
if (wDiff == 1 && y.parent) {
|
||||||
let oldRoot = y.parent;
|
let oldRoot = y.parent;
|
||||||
newRoot = rotateLeft(y.parent);
|
newRoot = rotateLeft(this, y.parent);
|
||||||
if (rotatingAroundRoot) {
|
|
||||||
this.root = newRoot;
|
|
||||||
}
|
|
||||||
this.record(
|
this.record(
|
||||||
"Final step of deletion rebalance: single rotation by parent of y",
|
"Final step of deletion rebalance: single rotation by parent of y",
|
||||||
oldRoot,
|
oldRoot,
|
||||||
|
@ -58,7 +54,7 @@ class WAVLTree extends AVLTree {
|
||||||
}
|
}
|
||||||
} else if (wDiff == 2 && v && v.parent) {
|
} else if (wDiff == 2 && v && v.parent) {
|
||||||
let oldRoot = v.parent;
|
let oldRoot = v.parent;
|
||||||
let intermediateRoot = rotateRight(v.parent);
|
let intermediateRoot = rotateRight(this, v.parent);
|
||||||
this.record(
|
this.record(
|
||||||
"Final step of deletion rebalance: first of double rotation by parent of v",
|
"Final step of deletion rebalance: first of double rotation by parent of v",
|
||||||
oldRoot,
|
oldRoot,
|
||||||
|
@ -66,10 +62,7 @@ class WAVLTree extends AVLTree {
|
||||||
);
|
);
|
||||||
|
|
||||||
oldRoot = v.parent;
|
oldRoot = v.parent;
|
||||||
newRoot = rotateLeft(v.parent);
|
newRoot = rotateLeft(this, v.parent);
|
||||||
if (rotatingAroundRoot) {
|
|
||||||
this.root = newRoot;
|
|
||||||
}
|
|
||||||
this.record(
|
this.record(
|
||||||
"Final step of deletion rebalance: second of double rotation by parent of v",
|
"Final step of deletion rebalance: second of double rotation by parent of v",
|
||||||
oldRoot,
|
oldRoot,
|
||||||
|
@ -132,8 +125,6 @@ class WAVLTree extends AVLTree {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
let rotatingAroundRoot = parent.parent == null;
|
|
||||||
|
|
||||||
let parentNodeDiffs = nodeDifferences(parent);
|
let parentNodeDiffs = nodeDifferences(parent);
|
||||||
if (parentNodeDiffs.sort().equals([1, 3])) {
|
if (parentNodeDiffs.sort().equals([1, 3])) {
|
||||||
if (parent.left === x) {
|
if (parent.left === x) {
|
||||||
|
@ -142,7 +133,6 @@ class WAVLTree extends AVLTree {
|
||||||
parent.right,
|
parent.right,
|
||||||
parent,
|
parent,
|
||||||
false,
|
false,
|
||||||
rotatingAroundRoot,
|
|
||||||
rotateLeft,
|
rotateLeft,
|
||||||
rotateRight
|
rotateRight
|
||||||
);
|
);
|
||||||
|
@ -152,7 +142,6 @@ class WAVLTree extends AVLTree {
|
||||||
parent.left,
|
parent.left,
|
||||||
parent,
|
parent,
|
||||||
true,
|
true,
|
||||||
rotatingAroundRoot,
|
|
||||||
rotateRight,
|
rotateRight,
|
||||||
rotateLeft
|
rotateLeft
|
||||||
);
|
);
|
||||||
|
|
Loading…
Reference in a new issue