updating post order animation
This commit is contained in:
committed by
JamesFlare1212
parent
50bbf8c2a7
commit
fea90f2b4d
@@ -1,11 +1,12 @@
|
|||||||
<!DOCTYPE html>
|
<!DOCTYPE html>
|
||||||
|
<!-- Author: Evan Lee -->
|
||||||
<html>
|
<html>
|
||||||
<head>
|
<head>
|
||||||
<meta charset="UTF-8">
|
<meta charset="UTF-8">
|
||||||
<title>Morris Post‑Order Traversal Animation & Code Display</title>
|
<title>Morris Post Order Traversal Animation & Code Display</title>
|
||||||
<link rel="stylesheet" href="style.css">
|
<link rel="stylesheet" href="style.css">
|
||||||
<!-- Load Konva.js -->
|
<!-- Load Konva.js -->
|
||||||
<script src="https://cdn.jsdelivr.net/npm/konva@8.3.13/konva.min.js"></script>
|
<script src="../../konva.js"></script>
|
||||||
<script src="script.js" defer></script>
|
<script src="script.js" defer></script>
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
|
|||||||
@@ -46,10 +46,10 @@ const codeContent = [
|
|||||||
'<span class="line-number">43.</span> }',
|
'<span class="line-number">43.</span> }',
|
||||||
'<span class="line-number">44.</span> reverse(tail); <span style="color:green">// restore structure</span>',
|
'<span class="line-number">44.</span> reverse(tail); <span style="color:green">// restore structure</span>',
|
||||||
'<span class="line-number">45.</span> }'
|
'<span class="line-number">45.</span> }'
|
||||||
];
|
];
|
||||||
|
|
||||||
// Initialize code display with proper structure for highlighting
|
// Initialize code display with proper structure for highlighting
|
||||||
function initCodeDisplay() {
|
function initCodeDisplay() {
|
||||||
const codeDisplay = document.getElementById('codeDisplay');
|
const codeDisplay = document.getElementById('codeDisplay');
|
||||||
codeContent.forEach((line, index) => {
|
codeContent.forEach((line, index) => {
|
||||||
const lineDiv = document.createElement('div');
|
const lineDiv = document.createElement('div');
|
||||||
@@ -58,10 +58,10 @@ const codeContent = [
|
|||||||
lineDiv.innerHTML = line;
|
lineDiv.innerHTML = line;
|
||||||
codeDisplay.appendChild(lineDiv);
|
codeDisplay.appendChild(lineDiv);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
// Function to highlight a specific line of code
|
// Function to highlight a specific line of code
|
||||||
function highlightLine(lineNum) {
|
function highlightLine(lineNum) {
|
||||||
// First, remove all highlights
|
// First, remove all highlights
|
||||||
const codeLines = document.querySelectorAll('.code-line');
|
const codeLines = document.querySelectorAll('.code-line');
|
||||||
codeLines.forEach(line => {
|
codeLines.forEach(line => {
|
||||||
@@ -78,10 +78,10 @@ const codeContent = [
|
|||||||
targetLine.scrollIntoView({ behavior: 'smooth', block: 'center' });
|
targetLine.scrollIntoView({ behavior: 'smooth', block: 'center' });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Wait for the "Next Step" button click.
|
// Wait for the "Next Step" button click.
|
||||||
function waitForNext() {
|
function waitForNext() {
|
||||||
return new Promise(resolve => {
|
return new Promise(resolve => {
|
||||||
const btn = document.getElementById('nextStep');
|
const btn = document.getElementById('nextStep');
|
||||||
btn.disabled = false;
|
btn.disabled = false;
|
||||||
@@ -90,23 +90,23 @@ const codeContent = [
|
|||||||
resolve();
|
resolve();
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
// Append text to the output.
|
// Append text to the output.
|
||||||
function appendOutput(text) {
|
function appendOutput(text) {
|
||||||
const out = document.getElementById('output');
|
const out = document.getElementById('output');
|
||||||
out.innerText += text;
|
out.innerText += text;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Update the explanation text.
|
// Update the explanation text.
|
||||||
function updateExplanation(text) {
|
function updateExplanation(text) {
|
||||||
document.getElementById('treeExplanation').innerHTML =
|
document.getElementById('treeExplanation').innerHTML =
|
||||||
'Post-order traversal output: <span id="output">' +
|
'Post-order traversal output: <span id="output">' +
|
||||||
document.getElementById('output').innerText + '</span><br>' + text;
|
document.getElementById('output').innerText + '</span><br>' + text;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Tree node class using Konva for visualization.
|
// Tree node class using Konva for visualization.
|
||||||
class TreeNode {
|
class TreeNode {
|
||||||
constructor(val, x, y) {
|
constructor(val, x, y) {
|
||||||
this.val = val;
|
this.val = val;
|
||||||
this.left = null;
|
this.left = null;
|
||||||
@@ -136,19 +136,19 @@ const codeContent = [
|
|||||||
this.threadEdge = null;
|
this.threadEdge = null;
|
||||||
this.reversedEdges = [];
|
this.reversedEdges = [];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Initialize Konva stage and layer.
|
// Initialize Konva stage and layer.
|
||||||
const stage = new Konva.Stage({
|
const stage = new Konva.Stage({
|
||||||
container: 'container',
|
container: 'container',
|
||||||
width: document.querySelector('.tree-container').clientWidth - 30,
|
width: document.querySelector('.tree-container').clientWidth - 30,
|
||||||
height: document.querySelector('.tree-container').clientHeight - 140
|
height: document.querySelector('.tree-container').clientHeight - 140
|
||||||
});
|
});
|
||||||
const layer = new Konva.Layer();
|
const layer = new Konva.Layer();
|
||||||
stage.add(layer);
|
stage.add(layer);
|
||||||
|
|
||||||
// Calculate connection points for arrow drawing.
|
// Calculate connection points for arrow drawing.
|
||||||
function calculateConnectionPoints(fromNode, toNode) {
|
function calculateConnectionPoints(fromNode, toNode) {
|
||||||
const nodeRadius = 20;
|
const nodeRadius = 20;
|
||||||
const dx = toNode.x - fromNode.x;
|
const dx = toNode.x - fromNode.x;
|
||||||
const dy = toNode.y - fromNode.y;
|
const dy = toNode.y - fromNode.y;
|
||||||
@@ -159,10 +159,10 @@ const codeContent = [
|
|||||||
toX: toNode.x - nodeRadius * Math.cos(angle),
|
toX: toNode.x - nodeRadius * Math.cos(angle),
|
||||||
toY: toNode.y - nodeRadius * Math.sin(angle)
|
toY: toNode.y - nodeRadius * Math.sin(angle)
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
// Create an arrow between two nodes.
|
// Create an arrow between two nodes.
|
||||||
function createArrow(fromNode, toNode, color = '#888', dashed = false) {
|
function createArrow(fromNode, toNode, color = '#888', dashed = false) {
|
||||||
const points = calculateConnectionPoints(fromNode, toNode);
|
const points = calculateConnectionPoints(fromNode, toNode);
|
||||||
const arrow = new Konva.Arrow({
|
const arrow = new Konva.Arrow({
|
||||||
points: [points.fromX, points.fromY, points.toX, points.toY],
|
points: [points.fromX, points.fromY, points.toX, points.toY],
|
||||||
@@ -176,95 +176,95 @@ const codeContent = [
|
|||||||
});
|
});
|
||||||
layer.add(arrow);
|
layer.add(arrow);
|
||||||
return arrow;
|
return arrow;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Draw an edge between two nodes.
|
// Draw an edge between two nodes.
|
||||||
function drawEdge(parent, child, isLeft = true) {
|
function drawEdge(parent, child, isLeft = true) {
|
||||||
const arrow = createArrow(parent, child);
|
const arrow = createArrow(parent, child);
|
||||||
layer.add(arrow);
|
layer.add(arrow);
|
||||||
if (isLeft) { parent.leftEdge = arrow; }
|
if (isLeft) { parent.leftEdge = arrow; }
|
||||||
else { parent.rightEdge = arrow; }
|
else { parent.rightEdge = arrow; }
|
||||||
arrow.moveToBottom();
|
arrow.moveToBottom();
|
||||||
return arrow;
|
return arrow;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Create and remove thread edges.
|
// Create and remove thread edges.
|
||||||
function createThreadEdge(fromNode, toNode) {
|
function createThreadEdge(fromNode, toNode) {
|
||||||
if (fromNode.threadEdge) { fromNode.threadEdge.destroy(); }
|
if (fromNode.threadEdge) { fromNode.threadEdge.destroy(); }
|
||||||
const threadArrow = createArrow(fromNode, toNode, '#ff5722', true);
|
const threadArrow = createArrow(fromNode, toNode, '#ff5722', true);
|
||||||
fromNode.threadEdge = threadArrow;
|
fromNode.threadEdge = threadArrow;
|
||||||
threadArrow.moveToTop();
|
threadArrow.moveToTop();
|
||||||
layer.draw();
|
layer.draw();
|
||||||
return threadArrow;
|
return threadArrow;
|
||||||
}
|
}
|
||||||
|
|
||||||
function removeThreadEdge(node) {
|
function removeThreadEdge(node) {
|
||||||
if (node && node.threadEdge) {
|
if (node && node.threadEdge) {
|
||||||
node.threadEdge.destroy();
|
node.threadEdge.destroy();
|
||||||
node.threadEdge = null;
|
node.threadEdge = null;
|
||||||
layer.draw();
|
layer.draw();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Highlight and unhighlight a node.
|
// Highlight and unhighlight a node.
|
||||||
function highlightNode(node, color = '#8bc34a') {
|
function highlightNode(node, color = '#8bc34a') {
|
||||||
if (node && node.shape) { node.shape.to({ fill: color, duration: 0.25 }); }
|
if (node && node.shape) { node.shape.to({ fill: color, duration: 0.25 }); }
|
||||||
}
|
}
|
||||||
|
|
||||||
function unhighlightNode(node, color = 'white') {
|
function unhighlightNode(node, color = 'white') {
|
||||||
if (node && node.shape) { node.shape.to({ fill: color, duration: 0.25 }); }
|
if (node && node.shape) { node.shape.to({ fill: color, duration: 0.25 }); }
|
||||||
}
|
}
|
||||||
|
|
||||||
// Calculate tree layout.
|
// Calculate tree layout.
|
||||||
const stageWidth = stage.width();
|
const stageWidth = stage.width();
|
||||||
const stageHeight = stage.height();
|
const stageHeight = stage.height();
|
||||||
const centerX = stageWidth / 2;
|
const centerX = stageWidth / 2;
|
||||||
const topY = 40;
|
const topY = 40;
|
||||||
const levelHeight = stageHeight / 4;
|
const levelHeight = stageHeight / 4;
|
||||||
|
|
||||||
// Build the 9-node binary tree.
|
// Build the 9-node binary tree.
|
||||||
const node1 = new TreeNode(1, centerX, topY);
|
const node1 = new TreeNode(1, centerX, topY);
|
||||||
const node2 = new TreeNode(2, centerX - stageWidth/4, topY + levelHeight);
|
const node2 = new TreeNode(2, centerX - stageWidth/4, topY + levelHeight);
|
||||||
const node3 = new TreeNode(3, centerX + stageWidth/4, topY + levelHeight);
|
const node3 = new TreeNode(3, centerX + stageWidth/4, topY + levelHeight);
|
||||||
const node4 = new TreeNode(4, centerX - stageWidth/3, topY + 2*levelHeight);
|
const node4 = new TreeNode(4, centerX - stageWidth/3, topY + 2*levelHeight);
|
||||||
const node5 = new TreeNode(5, centerX - stageWidth/6, topY + 2*levelHeight);
|
const node5 = new TreeNode(5, centerX - stageWidth/6, topY + 2*levelHeight);
|
||||||
const node6 = new TreeNode(6, centerX - stageWidth/4, topY + 3*levelHeight);
|
const node6 = new TreeNode(6, centerX - stageWidth/4, topY + 3*levelHeight);
|
||||||
const node7 = new TreeNode(7, centerX - stageWidth/12, topY + 3*levelHeight);
|
const node7 = new TreeNode(7, centerX - stageWidth/12, topY + 3*levelHeight);
|
||||||
const node8 = new TreeNode(8, centerX + stageWidth/3, topY + 2*levelHeight);
|
const node8 = new TreeNode(8, centerX + stageWidth/3, topY + 2*levelHeight);
|
||||||
const node9 = new TreeNode(9, centerX + stageWidth/4, topY + 3*levelHeight);
|
const node9 = new TreeNode(9, centerX + stageWidth/4, topY + 3*levelHeight);
|
||||||
|
|
||||||
node1.left = node2;
|
node1.left = node2;
|
||||||
node1.right = node3;
|
node1.right = node3;
|
||||||
node2.left = node4;
|
node2.left = node4;
|
||||||
node2.right = node5;
|
node2.right = node5;
|
||||||
node5.left = node6;
|
node5.left = node6;
|
||||||
node5.right = node7;
|
node5.right = node7;
|
||||||
node3.right = node8;
|
node3.right = node8;
|
||||||
node8.left = node9;
|
node8.left = node9;
|
||||||
|
|
||||||
const nodes = [node1, node2, node3, node4, node5, node6, node7, node8, node9];
|
const nodes = [node1, node2, node3, node4, node5, node6, node7, node8, node9];
|
||||||
nodes.forEach(n => {
|
nodes.forEach(n => {
|
||||||
layer.add(n.shape);
|
layer.add(n.shape);
|
||||||
layer.add(n.label);
|
layer.add(n.label);
|
||||||
});
|
});
|
||||||
|
|
||||||
drawEdge(node1, node2, true);
|
drawEdge(node1, node2, true);
|
||||||
drawEdge(node1, node3, false);
|
drawEdge(node1, node3, false);
|
||||||
drawEdge(node2, node4, true);
|
drawEdge(node2, node4, true);
|
||||||
drawEdge(node2, node5, false);
|
drawEdge(node2, node5, false);
|
||||||
drawEdge(node5, node6, true);
|
drawEdge(node5, node6, true);
|
||||||
drawEdge(node5, node7, false);
|
drawEdge(node5, node7, false);
|
||||||
drawEdge(node3, node8, false);
|
drawEdge(node3, node8, false);
|
||||||
drawEdge(node8, node9, true);
|
drawEdge(node8, node9, true);
|
||||||
|
|
||||||
nodes.forEach(n => {
|
nodes.forEach(n => {
|
||||||
n.shape.moveToTop();
|
n.shape.moveToTop();
|
||||||
n.label.moveToTop();
|
n.label.moveToTop();
|
||||||
});
|
});
|
||||||
layer.draw();
|
layer.draw();
|
||||||
|
|
||||||
// Visualize the reversal process.
|
// Visualize the reversal process.
|
||||||
async function visualizeReversal(head) {
|
async function visualizeReversal(head) {
|
||||||
const connections = [];
|
const connections = [];
|
||||||
let current = head;
|
let current = head;
|
||||||
while (current !== null && current.right !== null) {
|
while (current !== null && current.right !== null) {
|
||||||
@@ -292,33 +292,56 @@ const codeContent = [
|
|||||||
await waitForNext();
|
await waitForNext();
|
||||||
}
|
}
|
||||||
return prev;
|
return prev;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Restore the original tree structure.
|
// Restore the original tree structure.
|
||||||
async function visualizeRestore(head) {
|
async function visualizeRestore(head) {
|
||||||
|
// Clear all reversed edges
|
||||||
nodes.forEach(node => {
|
nodes.forEach(node => {
|
||||||
if (node.reversedEdges) {
|
if (node.reversedEdges) {
|
||||||
node.reversedEdges.forEach(edge => edge.destroy());
|
node.reversedEdges.forEach(edge => edge.destroy());
|
||||||
node.reversedEdges = [];
|
node.reversedEdges = [];
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
let current = head;
|
|
||||||
while (current !== null && current.right !== null) {
|
// Restore all original edges in the tree
|
||||||
if (!current.rightEdge) {
|
// First ensure the correct node relationships
|
||||||
current.rightEdge = createArrow(current, current.right, '#888');
|
node1.left = node2;
|
||||||
current.rightEdge.moveToBottom();
|
node1.right = node3;
|
||||||
}
|
node2.left = node4;
|
||||||
current = current.right;
|
node2.right = node5;
|
||||||
}
|
node5.left = node6;
|
||||||
|
node5.right = node7;
|
||||||
|
node3.right = node8;
|
||||||
|
node8.left = node9;
|
||||||
|
|
||||||
|
// Then recreate any missing visual edges
|
||||||
|
if (!node1.leftEdge) node1.leftEdge = createArrow(node1, node2, '#888');
|
||||||
|
if (!node1.rightEdge) node1.rightEdge = createArrow(node1, node3, '#888');
|
||||||
|
if (!node2.leftEdge) node2.leftEdge = createArrow(node2, node4, '#888');
|
||||||
|
if (!node2.rightEdge) node2.rightEdge = createArrow(node2, node5, '#888');
|
||||||
|
if (!node5.leftEdge) node5.leftEdge = createArrow(node5, node6, '#888');
|
||||||
|
if (!node5.rightEdge) node5.rightEdge = createArrow(node5, node7, '#888');
|
||||||
|
if (!node3.rightEdge) node3.rightEdge = createArrow(node3, node8, '#888');
|
||||||
|
if (!node8.leftEdge) node8.leftEdge = createArrow(node8, node9, '#888');
|
||||||
|
|
||||||
|
// Move all arrows to the bottom
|
||||||
|
nodes.forEach(node => {
|
||||||
|
if (node.leftEdge) node.leftEdge.moveToBottom();
|
||||||
|
if (node.rightEdge) node.rightEdge.moveToBottom();
|
||||||
|
});
|
||||||
|
|
||||||
|
// Move all nodes to the top
|
||||||
nodes.forEach(n => {
|
nodes.forEach(n => {
|
||||||
n.shape.moveToTop();
|
n.shape.moveToTop();
|
||||||
n.label.moveToTop();
|
n.label.moveToTop();
|
||||||
});
|
});
|
||||||
layer.draw();
|
|
||||||
}
|
|
||||||
|
|
||||||
// Reverse a chain of right pointers.
|
layer.draw();
|
||||||
async function reverseChain(head) {
|
}
|
||||||
|
|
||||||
|
// Reverse a chain of right pointers.
|
||||||
|
async function reverseChain(head) {
|
||||||
updateExplanation("Visualizing the reversal of pointers");
|
updateExplanation("Visualizing the reversal of pointers");
|
||||||
await waitForNext();
|
await waitForNext();
|
||||||
const reversedHead = await visualizeReversal(head);
|
const reversedHead = await visualizeReversal(head);
|
||||||
@@ -330,13 +353,27 @@ const codeContent = [
|
|||||||
curr = next;
|
curr = next;
|
||||||
}
|
}
|
||||||
return prev;
|
return prev;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Restore the chain.
|
// Restore the chain.
|
||||||
async function restoreChain(head) {
|
async function restoreChain(head) {
|
||||||
updateExplanation("Visualizing the restoration of original pointers");
|
updateExplanation("Visualizing the restoration of original pointers");
|
||||||
await waitForNext();
|
await waitForNext();
|
||||||
await visualizeRestore(head);
|
|
||||||
|
// Store the original tree structure before restoring
|
||||||
|
const originalTree = {
|
||||||
|
node1: { left: node1.left, right: node1.right },
|
||||||
|
node2: { left: node2.left, right: node2.right },
|
||||||
|
node3: { left: node3.left, right: node3.right },
|
||||||
|
node4: { left: node4.left, right: node4.right },
|
||||||
|
node5: { left: node5.left, right: node5.right },
|
||||||
|
node6: { left: node6.left, right: node6.right },
|
||||||
|
node7: { left: node7.left, right: node7.right },
|
||||||
|
node8: { left: node8.left, right: node8.right },
|
||||||
|
node9: { left: node9.left, right: node9.right }
|
||||||
|
};
|
||||||
|
|
||||||
|
// Reverse the linked list back
|
||||||
let prev = null, curr = head, next;
|
let prev = null, curr = head, next;
|
||||||
while (curr !== null) {
|
while (curr !== null) {
|
||||||
next = curr.right;
|
next = curr.right;
|
||||||
@@ -344,11 +381,34 @@ const codeContent = [
|
|||||||
prev = curr;
|
prev = curr;
|
||||||
curr = next;
|
curr = next;
|
||||||
}
|
}
|
||||||
return prev;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Reverse traverse the right edge of a subtree.
|
// Restore the original tree structure
|
||||||
async function reverseTraverseRightEdge(head) {
|
node1.left = originalTree.node1.left;
|
||||||
|
node1.right = originalTree.node1.right;
|
||||||
|
node2.left = originalTree.node2.left;
|
||||||
|
node2.right = originalTree.node2.right;
|
||||||
|
node3.left = originalTree.node3.left;
|
||||||
|
node3.right = originalTree.node3.right;
|
||||||
|
node4.left = originalTree.node4.left;
|
||||||
|
node4.right = originalTree.node4.right;
|
||||||
|
node5.left = originalTree.node5.left;
|
||||||
|
node5.right = originalTree.node5.right;
|
||||||
|
node6.left = originalTree.node6.left;
|
||||||
|
node6.right = originalTree.node6.right;
|
||||||
|
node7.left = originalTree.node7.left;
|
||||||
|
node7.right = originalTree.node7.right;
|
||||||
|
node8.left = originalTree.node8.left;
|
||||||
|
node8.right = originalTree.node8.right;
|
||||||
|
node9.left = originalTree.node9.left;
|
||||||
|
node9.right = originalTree.node9.right;
|
||||||
|
|
||||||
|
await visualizeRestore(prev);
|
||||||
|
|
||||||
|
return prev;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Reverse traverse the right edge of a subtree.
|
||||||
|
async function reverseTraverseRightEdge(head) {
|
||||||
if (!head) return;
|
if (!head) return;
|
||||||
highlightLine(-1); // Clear code highlighting during reverse traversal
|
highlightLine(-1); // Clear code highlighting during reverse traversal
|
||||||
updateExplanation("Executing reverseTraverseRightEdge on node " + head.val);
|
updateExplanation("Executing reverseTraverseRightEdge on node " + head.val);
|
||||||
@@ -371,10 +431,10 @@ const codeContent = [
|
|||||||
await waitForNext();
|
await waitForNext();
|
||||||
await restoreChain(tail);
|
await restoreChain(tail);
|
||||||
layer.draw();
|
layer.draw();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Morris Post‑Order Traversal Animation.
|
// Morris Post‑Order Traversal Animation.
|
||||||
async function postorderTraversal(root) {
|
async function postorderTraversal(root) {
|
||||||
// Ensure all nodes are white at start
|
// Ensure all nodes are white at start
|
||||||
nodes.forEach(n => { unhighlightNode(n, 'white'); });
|
nodes.forEach(n => { unhighlightNode(n, 'white'); });
|
||||||
|
|
||||||
@@ -385,14 +445,16 @@ const codeContent = [
|
|||||||
|
|
||||||
highlightLine(1);
|
highlightLine(1);
|
||||||
updateExplanation("Initializing current = root (node 1)");
|
updateExplanation("Initializing current = root (node 1)");
|
||||||
|
let current = root;
|
||||||
|
// Highlight current node immediately after initialization
|
||||||
|
highlightNode(current, '#ffeb3b');
|
||||||
|
layer.draw();
|
||||||
await waitForNext();
|
await waitForNext();
|
||||||
|
|
||||||
highlightLine(2);
|
highlightLine(2);
|
||||||
updateExplanation("Declaring rightmost pointer");
|
updateExplanation("Declaring rightmost pointer");
|
||||||
await waitForNext();
|
await waitForNext();
|
||||||
|
|
||||||
let current = root;
|
|
||||||
|
|
||||||
// Main loop
|
// Main loop
|
||||||
while (current !== null) {
|
while (current !== null) {
|
||||||
// Clear previous highlighting
|
// Clear previous highlighting
|
||||||
@@ -546,16 +608,16 @@ const codeContent = [
|
|||||||
n.label.moveToTop();
|
n.label.moveToTop();
|
||||||
});
|
});
|
||||||
layer.draw();
|
layer.draw();
|
||||||
}
|
}
|
||||||
|
|
||||||
window.addEventListener('resize', function() {
|
window.addEventListener('resize', function() {
|
||||||
stage.width(document.querySelector('.tree-container').clientWidth - 30);
|
stage.width(document.querySelector('.tree-container').clientWidth - 30);
|
||||||
stage.height(document.querySelector('.tree-container').clientHeight - 140);
|
stage.height(document.querySelector('.tree-container').clientHeight - 140);
|
||||||
layer.draw();
|
layer.draw();
|
||||||
});
|
});
|
||||||
|
|
||||||
window.onload = function() {
|
window.onload = function() {
|
||||||
initCodeDisplay();
|
initCodeDisplay();
|
||||||
document.getElementById('nextStep').disabled = false;
|
document.getElementById('nextStep').disabled = false;
|
||||||
postorderTraversal(node1);
|
postorderTraversal(node1);
|
||||||
};
|
};
|
||||||
Reference in New Issue
Block a user