fix: Ensure all affected nodes are being highlighted

Fixes #9

Signed-off-by: Matej Focko <mfocko@redhat.com>
This commit is contained in:
Matej Focko 2022-05-16 18:36:31 +02:00
parent 030cd9a701
commit 43ade1120b
Signed by: mfocko
GPG key ID: 7C47D46246790496
5 changed files with 34 additions and 20 deletions

20
avl.js
View file

@ -41,15 +41,16 @@ class AVLTree extends RankedTree {
if (rotatingAroundRoot) {
this.root = newRoot;
}
this.record("Fixing 0-child by single rotation: by z", z);
this.record("Fixing 0-child by single rotation: by z", z, newRoot);
z.demote();
this.record("Fixing 0-child by single rotation: demoting z", z);
} else if (nodeDifference(y) == 1) {
rotateLeft(x);
let intermediateRoot = rotateLeft(x);
this.record(
"Fixing 0-child by double-rotation: first rotation by x",
x
x,
intermediateRoot
);
newRoot = rotateRight(z);
@ -58,7 +59,8 @@ class AVLTree extends RankedTree {
}
this.record(
"Fixing 0-child by double-rotation: second rotation by z",
z
z,
newRoot
);
y.promote();
@ -129,8 +131,12 @@ class AVLTree extends RankedTree {
newRoot = rotateLeft(x);
break;
default:
rotateRight(y);
this.record("AVL deletion, fixing by double-rotation: by y", y);
let intermediateRoot = rotateRight(y);
this.record(
"AVL deletion, fixing by double-rotation: by y",
y,
intermediateRoot
);
newRoot = rotateLeft(x);
break;
@ -138,7 +144,7 @@ class AVLTree extends RankedTree {
if (rotatingAroundRoot) {
this.root = newRoot;
}
this.record("AVL deletion, fixing by rotation by x", x);
this.record("AVL deletion, fixing by rotation by x", x, newRoot);
[newRoot.left, newRoot.right, newRoot]
.filter((x) => x)

View file

@ -4,7 +4,7 @@ class RankedTree {
this.recorder = null;
}
_getUnwrappedGraph(highlightedNode) {
_getUnwrappedGraph(...highlightedNodes) {
let result = [];
let q = new Queue();
@ -18,8 +18,9 @@ class RankedTree {
}
let [value, rank] = [node.value, node.rank];
let highlight =
node === highlightedNode ? ', color="blue", penwidth=3' : "";
let highlight = highlightedNodes.includes(node)
? ', color="blue", penwidth=3'
: "";
result.push(
`\t"Node(${value})" [label="${value}, ${rank}"${highlight}];\n`
);
@ -46,10 +47,10 @@ class RankedTree {
return result;
}
toDot(highlightedNode) {
toDot(...highlightedNodes) {
return [
"digraph {\n",
...this._getUnwrappedGraph(highlightedNode),
...this._getUnwrappedGraph(...highlightedNodes),
"}\n",
];
}
@ -58,11 +59,11 @@ class RankedTree {
return this.toDot().join("\n");
}
record(message, highlightedNode) {
record(message, ...highlightedNodes) {
if (!this.recorder) {
return;
}
this.recorder.record(this, message, highlightedNode);
this.recorder.record(this, message, ...highlightedNodes);
}
rank() {

View file

@ -16,6 +16,7 @@ class RAVLTree extends WAVLTree {
deleteRebalance(node, parent) {
// no-op
this.record("No rebalancing occurs");
return;
}
}

View file

@ -84,10 +84,10 @@ class Recorder {
throw "not implemented!";
}
record(tree, message, highlightedNode) {
record(tree, message, ...highlightedNodes) {
// TODO: adjust join if necessary
this.states.push(
new Record(tree.toDot(highlightedNode).join(""), message)
new Record(tree.toDot(...highlightedNodes).join(""), message)
);
this.render();
}

14
wavl.js
View file

@ -32,13 +32,15 @@ class WAVLTree extends AVLTree {
let wDiff = nodeDifference(w, y);
if (wDiff == 1 && y.parent) {
let oldRoot = y.parent;
newRoot = rotateLeft(y.parent);
if (rotatingAroundRoot) {
this.root = newRoot;
}
this.record(
"Final step of deletion rebalance: single rotation by parent of y",
y.parent
oldRoot,
newRoot
);
y.promote();
@ -55,19 +57,23 @@ class WAVLTree extends AVLTree {
);
}
} else if (wDiff == 2 && v && v.parent) {
rotateRight(v.parent);
let oldRoot = v.parent;
let intermediateRoot = rotateRight(v.parent);
this.record(
"Final step of deletion rebalance: first of double rotation by parent of v",
v.parent
oldRoot,
intermediateRoot
);
oldRoot = v.parent;
newRoot = rotateLeft(v.parent);
if (rotatingAroundRoot) {
this.root = newRoot;
}
this.record(
"Final step of deletion rebalance: second of double rotation by parent of v",
v.parent
oldRoot,
newRoot
);
v.promote().promote();