@tomaszjarosz/react-visualizers 0.2.3 → 0.2.7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.cjs +233 -51
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +233 -51
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -5599,6 +5599,7 @@ const LinkedHashMapVisualizerComponent = ({
|
|
|
5599
5599
|
});
|
|
5600
5600
|
const stepData = currentStepData || {
|
|
5601
5601
|
operation: "init",
|
|
5602
|
+
key: "",
|
|
5602
5603
|
buckets: [],
|
|
5603
5604
|
linkedOrder: [],
|
|
5604
5605
|
description: ""
|
|
@@ -5679,9 +5680,30 @@ const LinkedHashMapVisualizerComponent = ({
|
|
|
5679
5680
|
] }) }),
|
|
5680
5681
|
/* @__PURE__ */ jsx("div", { className: "p-4", children: /* @__PURE__ */ jsxs("div", { className: `flex gap-4 ${showCode ? "flex-col lg:flex-row" : ""}`, children: [
|
|
5681
5682
|
/* @__PURE__ */ jsxs(VisualizationArea, { minHeight: 400, className: showCode ? "flex-1" : "w-full", children: [
|
|
5682
|
-
/* @__PURE__ */ jsxs("div", { className: "mb-
|
|
5683
|
-
/* @__PURE__ */
|
|
5684
|
-
|
|
5683
|
+
/* @__PURE__ */ jsxs("div", { className: "mb-4 p-4 bg-gradient-to-r from-orange-50 to-amber-50 rounded-xl border-2 border-orange-200", children: [
|
|
5684
|
+
/* @__PURE__ */ jsxs("div", { className: "text-sm font-bold text-orange-800 mb-3 flex items-center gap-2", children: [
|
|
5685
|
+
/* @__PURE__ */ jsx("span", { className: "text-lg", children: "🔗" }),
|
|
5686
|
+
" LinkedHashMap = HashMap + LinkedList"
|
|
5687
|
+
] }),
|
|
5688
|
+
/* @__PURE__ */ jsxs("div", { className: "grid grid-cols-1 sm:grid-cols-2 gap-3", children: [
|
|
5689
|
+
/* @__PURE__ */ jsxs("div", { className: "bg-white p-3 rounded-lg border border-orange-200", children: [
|
|
5690
|
+
/* @__PURE__ */ jsx("div", { className: "text-xs font-semibold text-gray-700 mb-1", children: "🗂️ Hash Table" }),
|
|
5691
|
+
/* @__PURE__ */ jsx("div", { className: "text-[10px] text-gray-500", children: "O(1) get/put • Same as HashMap" })
|
|
5692
|
+
] }),
|
|
5693
|
+
/* @__PURE__ */ jsxs("div", { className: "bg-white p-3 rounded-lg border border-orange-200", children: [
|
|
5694
|
+
/* @__PURE__ */ jsx("div", { className: "text-xs font-semibold text-gray-700 mb-1", children: "🔗 Doubly Linked List" }),
|
|
5695
|
+
/* @__PURE__ */ jsxs("div", { className: "text-[10px] text-gray-500", children: [
|
|
5696
|
+
accessOrder ? "Access order (LRU cache)" : "Insertion order",
|
|
5697
|
+
" • O(1) reorder"
|
|
5698
|
+
] })
|
|
5699
|
+
] })
|
|
5700
|
+
] }),
|
|
5701
|
+
stepData.operation === "access" && /* @__PURE__ */ jsx("div", { className: "mt-3 p-2 bg-orange-100 rounded-lg border border-orange-300", children: /* @__PURE__ */ jsxs("div", { className: "text-xs text-center text-orange-800", children: [
|
|
5702
|
+
/* @__PURE__ */ jsx("span", { className: "font-bold", children: "LRU Update:" }),
|
|
5703
|
+
' Entry "',
|
|
5704
|
+
stepData.key,
|
|
5705
|
+
'" moved to end of list (most recently used)'
|
|
5706
|
+
] }) })
|
|
5685
5707
|
] }),
|
|
5686
5708
|
/* @__PURE__ */ jsxs("div", { className: "mb-4", children: [
|
|
5687
5709
|
/* @__PURE__ */ jsxs("div", { className: "text-sm font-medium text-gray-700 mb-2", children: [
|
|
@@ -5713,22 +5735,31 @@ const LinkedHashMapVisualizerComponent = ({
|
|
|
5713
5735
|
] }, eIdx)) : /* @__PURE__ */ jsx("div", { className: "text-[10px] text-gray-400 mt-1", children: "∅" }) })
|
|
5714
5736
|
] }, idx)) })
|
|
5715
5737
|
] }),
|
|
5716
|
-
/* @__PURE__ */ jsxs("div", { className: "mb-4", children: [
|
|
5717
|
-
/* @__PURE__ */
|
|
5718
|
-
|
|
5719
|
-
|
|
5720
|
-
|
|
5721
|
-
|
|
5722
|
-
|
|
5723
|
-
|
|
5724
|
-
|
|
5725
|
-
|
|
5726
|
-
|
|
5727
|
-
}
|
|
5728
|
-
|
|
5729
|
-
|
|
5730
|
-
|
|
5731
|
-
|
|
5738
|
+
/* @__PURE__ */ jsxs("div", { className: "mb-4 p-3 bg-gradient-to-r from-orange-100 to-amber-100 rounded-xl border-2 border-orange-300", children: [
|
|
5739
|
+
/* @__PURE__ */ jsxs("div", { className: "text-sm font-semibold text-orange-800 mb-2 flex items-center gap-2", children: [
|
|
5740
|
+
/* @__PURE__ */ jsx("span", { children: "🔗" }),
|
|
5741
|
+
" ",
|
|
5742
|
+
accessOrder ? "Access Order (LRU: oldest → newest)" : "Insertion Order"
|
|
5743
|
+
] }),
|
|
5744
|
+
/* @__PURE__ */ jsxs("div", { className: "bg-white rounded-lg p-3 border border-orange-200", children: [
|
|
5745
|
+
/* @__PURE__ */ jsx("div", { className: "flex flex-wrap items-center gap-1", children: linkedOrder.length > 0 ? /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
5746
|
+
/* @__PURE__ */ jsx("div", { className: "px-2 py-1 bg-gray-100 text-[10px] text-gray-600 rounded font-semibold", children: "HEAD" }),
|
|
5747
|
+
/* @__PURE__ */ jsx("span", { className: "text-orange-400 font-bold", children: "→" }),
|
|
5748
|
+
linkedOrder.map((key, idx) => /* @__PURE__ */ jsxs(React.Fragment, { children: [
|
|
5749
|
+
idx > 0 && /* @__PURE__ */ jsx("span", { className: "text-orange-400 font-bold", children: "⇄" }),
|
|
5750
|
+
/* @__PURE__ */ jsx(
|
|
5751
|
+
"div",
|
|
5752
|
+
{
|
|
5753
|
+
className: `px-3 py-1 text-xs font-bold rounded-full transition-colors ${getLinkedNodeStyle(key)}`,
|
|
5754
|
+
children: key
|
|
5755
|
+
}
|
|
5756
|
+
)
|
|
5757
|
+
] }, key)),
|
|
5758
|
+
/* @__PURE__ */ jsx("span", { className: "text-orange-400 font-bold", children: "→" }),
|
|
5759
|
+
/* @__PURE__ */ jsx("div", { className: "px-2 py-1 bg-gray-100 text-[10px] text-gray-600 rounded font-semibold", children: "TAIL" })
|
|
5760
|
+
] }) : /* @__PURE__ */ jsx("span", { className: "text-xs text-gray-400 italic", children: "HEAD → TAIL (empty)" }) }),
|
|
5761
|
+
linkedOrder.length > 0 && /* @__PURE__ */ jsx("div", { className: "mt-2 pt-2 border-t border-orange-200 text-[10px] text-gray-500 text-center", children: "Doubly linked: each entry has prev/next pointers" })
|
|
5762
|
+
] })
|
|
5732
5763
|
] }),
|
|
5733
5764
|
accessOrder && /* @__PURE__ */ jsx("div", { className: "mb-4 p-3 bg-blue-50 rounded-lg", children: /* @__PURE__ */ jsxs("div", { className: "text-xs text-blue-700", children: [
|
|
5734
5765
|
/* @__PURE__ */ jsx("strong", { children: "LRU Cache Usage:" }),
|
|
@@ -6975,6 +7006,59 @@ const TreeSetVisualizerComponent = ({
|
|
|
6975
7006
|
] }) }),
|
|
6976
7007
|
/* @__PURE__ */ jsx("div", { className: "p-4", children: /* @__PURE__ */ jsxs("div", { className: `flex gap-4 ${showCode ? "flex-col lg:flex-row" : ""}`, children: [
|
|
6977
7008
|
/* @__PURE__ */ jsxs(VisualizationArea, { minHeight: 400, className: showCode ? "flex-1" : "w-full", children: [
|
|
7009
|
+
/* @__PURE__ */ jsxs("div", { className: "mb-4 p-4 bg-gradient-to-r from-emerald-50 to-teal-50 rounded-xl border-2 border-emerald-200", children: [
|
|
7010
|
+
/* @__PURE__ */ jsxs("div", { className: "text-sm font-bold text-emerald-800 mb-3 flex items-center gap-2", children: [
|
|
7011
|
+
/* @__PURE__ */ jsx("span", { className: "text-lg", children: "🌳" }),
|
|
7012
|
+
" Binary Search Tree Property"
|
|
7013
|
+
] }),
|
|
7014
|
+
/* @__PURE__ */ jsxs("div", { className: "font-mono text-sm bg-white rounded-lg p-3 border border-emerald-200", children: [
|
|
7015
|
+
/* @__PURE__ */ jsxs("div", { className: "text-center text-emerald-700 font-bold text-base mb-2", children: [
|
|
7016
|
+
"left < ",
|
|
7017
|
+
/* @__PURE__ */ jsx("span", { className: "text-gray-800", children: "node" }),
|
|
7018
|
+
" < right"
|
|
7019
|
+
] }),
|
|
7020
|
+
/* @__PURE__ */ jsx("div", { className: "text-xs text-gray-500 text-center", children: "All values in left subtree are smaller • All values in right subtree are larger" })
|
|
7021
|
+
] }),
|
|
7022
|
+
currentStepData.operation === "add" && currentStepData.value !== void 0 && currentNode !== void 0 && currentNode !== currentStepData.value && /* @__PURE__ */ jsx("div", { className: "mt-3 p-2 bg-white rounded-lg border border-emerald-200", children: /* @__PURE__ */ jsxs("div", { className: "text-xs text-center", children: [
|
|
7023
|
+
/* @__PURE__ */ jsx("span", { className: "font-semibold text-emerald-700", children: "Comparing:" }),
|
|
7024
|
+
" ",
|
|
7025
|
+
/* @__PURE__ */ jsxs("span", { className: "font-mono", children: [
|
|
7026
|
+
currentStepData.value,
|
|
7027
|
+
" ",
|
|
7028
|
+
currentStepData.value < currentNode ? "<" : ">",
|
|
7029
|
+
" ",
|
|
7030
|
+
currentNode
|
|
7031
|
+
] }),
|
|
7032
|
+
" → ",
|
|
7033
|
+
/* @__PURE__ */ jsxs("span", { className: `font-bold ${currentStepData.value < currentNode ? "text-blue-600" : "text-orange-600"}`, children: [
|
|
7034
|
+
"Go ",
|
|
7035
|
+
currentStepData.value < currentNode ? "LEFT" : "RIGHT"
|
|
7036
|
+
] })
|
|
7037
|
+
] }) }),
|
|
7038
|
+
currentStepData.operation === "contains" && currentStepData.value !== void 0 && currentNode !== void 0 && !found && path.length > 0 && path[path.length - 1] !== currentStepData.value && /* @__PURE__ */ jsx("div", { className: "mt-3 p-2 bg-white rounded-lg border border-emerald-200", children: /* @__PURE__ */ jsxs("div", { className: "text-xs text-center", children: [
|
|
7039
|
+
/* @__PURE__ */ jsx("span", { className: "font-semibold text-emerald-700", children: "Comparing:" }),
|
|
7040
|
+
" ",
|
|
7041
|
+
/* @__PURE__ */ jsxs("span", { className: "font-mono", children: [
|
|
7042
|
+
currentStepData.value,
|
|
7043
|
+
" ",
|
|
7044
|
+
currentStepData.value < currentNode ? "<" : ">",
|
|
7045
|
+
" ",
|
|
7046
|
+
currentNode
|
|
7047
|
+
] }),
|
|
7048
|
+
" → ",
|
|
7049
|
+
/* @__PURE__ */ jsxs("span", { className: `font-bold ${currentStepData.value < currentNode ? "text-blue-600" : "text-orange-600"}`, children: [
|
|
7050
|
+
"Go ",
|
|
7051
|
+
currentStepData.value < currentNode ? "LEFT" : "RIGHT"
|
|
7052
|
+
] })
|
|
7053
|
+
] }) }),
|
|
7054
|
+
found === true && /* @__PURE__ */ jsx("div", { className: "mt-3 p-2 bg-green-100 rounded-lg border border-green-300", children: /* @__PURE__ */ jsxs("div", { className: "text-xs text-center text-green-800 font-bold", children: [
|
|
7055
|
+
"✓ Found! ",
|
|
7056
|
+
currentStepData.value,
|
|
7057
|
+
" == ",
|
|
7058
|
+
currentNode
|
|
7059
|
+
] }) }),
|
|
7060
|
+
found === false && /* @__PURE__ */ jsx("div", { className: "mt-3 p-2 bg-red-100 rounded-lg border border-red-300", children: /* @__PURE__ */ jsx("div", { className: "text-xs text-center text-red-800 font-bold", children: "✗ Not found! Reached null (no more children to check)" }) })
|
|
7061
|
+
] }),
|
|
6978
7062
|
/* @__PURE__ */ jsxs("div", { className: "mb-4", children: [
|
|
6979
7063
|
/* @__PURE__ */ jsx("div", { className: "text-sm font-medium text-gray-700 mb-2", children: "Binary Search Tree" }),
|
|
6980
7064
|
/* @__PURE__ */ jsx("div", { className: "bg-gray-50 rounded-lg p-2 overflow-x-auto", children: tree ? /* @__PURE__ */ jsx("svg", { width: "300", height: "250", className: "mx-auto", children: renderTree(tree) }) : /* @__PURE__ */ jsx("div", { className: "h-32 flex items-center justify-center text-gray-400 text-sm", children: "Empty tree" }) })
|
|
@@ -7274,7 +7358,7 @@ const EnumSetVisualizerComponent = ({
|
|
|
7274
7358
|
/* @__PURE__ */ jsxs(
|
|
7275
7359
|
"div",
|
|
7276
7360
|
{
|
|
7277
|
-
className: `w-14 h-10 flex flex-col items-center justify-center text-xs font-medium rounded transition-
|
|
7361
|
+
className: `w-14 h-10 flex flex-col items-center justify-center text-xs font-medium rounded transition-colors duration-200 ${getBitStyle(idx)}`,
|
|
7278
7362
|
children: [
|
|
7279
7363
|
/* @__PURE__ */ jsxs("span", { className: "text-[10px] opacity-80", children: [
|
|
7280
7364
|
"bit ",
|
|
@@ -7340,27 +7424,27 @@ const EnumSetVisualizerComponent = ({
|
|
|
7340
7424
|
bitmask === 0 && /* @__PURE__ */ jsx("span", { className: "text-xs text-gray-400 italic", children: "Empty set" })
|
|
7341
7425
|
] })
|
|
7342
7426
|
] }),
|
|
7343
|
-
/* @__PURE__ */
|
|
7344
|
-
/* @__PURE__ */
|
|
7345
|
-
|
|
7346
|
-
|
|
7347
|
-
|
|
7348
|
-
|
|
7349
|
-
|
|
7350
|
-
|
|
7351
|
-
/* @__PURE__ */ jsx("
|
|
7352
|
-
"
|
|
7353
|
-
|
|
7354
|
-
/* @__PURE__ */ jsxs("div", { children: [
|
|
7355
|
-
/* @__PURE__ */ jsx("span", { className: "text-green-600", children: "EnumSet:" }),
|
|
7356
|
-
" O(1) bit operation"
|
|
7427
|
+
/* @__PURE__ */ jsxs("div", { className: "mb-4 p-4 bg-gradient-to-r from-green-50 to-lime-50 rounded-xl border-2 border-green-200", children: [
|
|
7428
|
+
/* @__PURE__ */ jsxs("div", { className: "text-sm font-bold text-green-800 mb-3 flex items-center gap-2", children: [
|
|
7429
|
+
/* @__PURE__ */ jsx("span", { className: "text-lg", children: "💡" }),
|
|
7430
|
+
" Why EnumSet? Memory Efficiency!"
|
|
7431
|
+
] }),
|
|
7432
|
+
/* @__PURE__ */ jsxs("div", { className: "grid grid-cols-2 gap-4", children: [
|
|
7433
|
+
/* @__PURE__ */ jsxs("div", { className: "bg-white p-3 rounded-lg border-2 border-green-300", children: [
|
|
7434
|
+
/* @__PURE__ */ jsx("div", { className: "text-sm font-bold text-green-700 mb-2", children: "EnumSet" }),
|
|
7435
|
+
/* @__PURE__ */ jsx("div", { className: "text-2xl font-bold text-green-600 mb-1", children: "8 bytes" }),
|
|
7436
|
+
/* @__PURE__ */ jsx("div", { className: "text-xs text-gray-600", children: "1 long for up to 64 enum values" }),
|
|
7437
|
+
/* @__PURE__ */ jsx("div", { className: "mt-2 text-xs text-green-600", children: "✓ Single CPU instruction per operation" })
|
|
7357
7438
|
] }),
|
|
7358
|
-
/* @__PURE__ */ jsxs("div", { children: [
|
|
7359
|
-
/* @__PURE__ */ jsx("
|
|
7360
|
-
"
|
|
7439
|
+
/* @__PURE__ */ jsxs("div", { className: "bg-white p-3 rounded-lg border-2 border-gray-300", children: [
|
|
7440
|
+
/* @__PURE__ */ jsx("div", { className: "text-sm font-bold text-gray-500 mb-2", children: "HashSet" }),
|
|
7441
|
+
/* @__PURE__ */ jsx("div", { className: "text-2xl font-bold text-gray-500 mb-1", children: "~280 bytes" }),
|
|
7442
|
+
/* @__PURE__ */ jsx("div", { className: "text-xs text-gray-500", children: "For 7 enum values (~40 bytes each)" }),
|
|
7443
|
+
/* @__PURE__ */ jsx("div", { className: "mt-2 text-xs text-gray-500", children: "Hash computation + object overhead" })
|
|
7361
7444
|
] })
|
|
7362
|
-
] })
|
|
7363
|
-
|
|
7445
|
+
] }),
|
|
7446
|
+
/* @__PURE__ */ jsx("div", { className: "mt-3 text-center", children: /* @__PURE__ */ jsx("span", { className: "inline-block px-3 py-1 bg-green-100 text-green-800 rounded-full text-sm font-bold", children: "35x smaller memory footprint!" }) })
|
|
7447
|
+
] }),
|
|
7364
7448
|
/* @__PURE__ */ jsx(
|
|
7365
7449
|
StatusPanel,
|
|
7366
7450
|
{
|
|
@@ -7438,6 +7522,7 @@ const HEAP_CODE = [
|
|
|
7438
7522
|
const LEGEND_ITEMS$6 = [
|
|
7439
7523
|
{ color: "bg-purple-100", label: "Root (min)", border: "#c4b5fd" },
|
|
7440
7524
|
{ color: "bg-purple-500", label: "Active" },
|
|
7525
|
+
{ color: "bg-purple-200", label: "Sift Path", border: "#a78bfa" },
|
|
7441
7526
|
{ color: "bg-yellow-300", label: "Comparing" },
|
|
7442
7527
|
{ color: "bg-green-400", label: "Swapped" }
|
|
7443
7528
|
];
|
|
@@ -7454,6 +7539,15 @@ function generateHeapSteps() {
|
|
|
7454
7539
|
if (op === "offer" && value !== void 0) {
|
|
7455
7540
|
heap.push(value);
|
|
7456
7541
|
let idx = heap.length - 1;
|
|
7542
|
+
const getPathToRoot = (index) => {
|
|
7543
|
+
const path = [index];
|
|
7544
|
+
let i = index;
|
|
7545
|
+
while (i > 0) {
|
|
7546
|
+
i = Math.floor((i - 1) / 2);
|
|
7547
|
+
path.push(i);
|
|
7548
|
+
}
|
|
7549
|
+
return path;
|
|
7550
|
+
};
|
|
7457
7551
|
steps.push({
|
|
7458
7552
|
operation: "offer",
|
|
7459
7553
|
value,
|
|
@@ -7461,7 +7555,9 @@ function generateHeapSteps() {
|
|
|
7461
7555
|
description: `offer(${value}): Add to end of heap at index ${idx}`,
|
|
7462
7556
|
codeLine: 1,
|
|
7463
7557
|
variables: { value, index: idx },
|
|
7464
|
-
highlightIndex: idx
|
|
7558
|
+
highlightIndex: idx,
|
|
7559
|
+
siftPath: getPathToRoot(idx),
|
|
7560
|
+
currentIndex: idx
|
|
7465
7561
|
});
|
|
7466
7562
|
while (idx > 0) {
|
|
7467
7563
|
const parentIdx = Math.floor((idx - 1) / 2);
|
|
@@ -7476,7 +7572,9 @@ function generateHeapSteps() {
|
|
|
7476
7572
|
child: heap[idx],
|
|
7477
7573
|
parentVal: heap[parentIdx]
|
|
7478
7574
|
},
|
|
7479
|
-
compareIndices: [idx, parentIdx]
|
|
7575
|
+
compareIndices: [idx, parentIdx],
|
|
7576
|
+
siftPath: getPathToRoot(idx),
|
|
7577
|
+
currentIndex: idx
|
|
7480
7578
|
});
|
|
7481
7579
|
if (heap[idx] < heap[parentIdx]) {
|
|
7482
7580
|
[heap[idx], heap[parentIdx]] = [heap[parentIdx], heap[idx]];
|
|
@@ -7487,7 +7585,9 @@ function generateHeapSteps() {
|
|
|
7487
7585
|
codeLine: 8,
|
|
7488
7586
|
variables: { swapped: heap[parentIdx], index: parentIdx },
|
|
7489
7587
|
swapIndices: [idx, parentIdx],
|
|
7490
|
-
highlightIndex: parentIdx
|
|
7588
|
+
highlightIndex: parentIdx,
|
|
7589
|
+
siftPath: getPathToRoot(parentIdx),
|
|
7590
|
+
currentIndex: parentIdx
|
|
7491
7591
|
});
|
|
7492
7592
|
idx = parentIdx;
|
|
7493
7593
|
} else {
|
|
@@ -7497,7 +7597,9 @@ function generateHeapSteps() {
|
|
|
7497
7597
|
description: `siftUp: ${heap[idx]} >= ${heap[parentIdx]}, heap property satisfied!`,
|
|
7498
7598
|
codeLine: 7,
|
|
7499
7599
|
variables: { index: idx },
|
|
7500
|
-
highlightIndex: idx
|
|
7600
|
+
highlightIndex: idx,
|
|
7601
|
+
siftPath: getPathToRoot(idx),
|
|
7602
|
+
currentIndex: idx
|
|
7501
7603
|
});
|
|
7502
7604
|
break;
|
|
7503
7605
|
}
|
|
@@ -7507,6 +7609,21 @@ function generateHeapSteps() {
|
|
|
7507
7609
|
const removed = heap[0];
|
|
7508
7610
|
const last = heap.pop();
|
|
7509
7611
|
if (last === void 0) continue;
|
|
7612
|
+
const getPathToLeaf = (heapSize, startIdx) => {
|
|
7613
|
+
const path = [startIdx];
|
|
7614
|
+
let i = startIdx;
|
|
7615
|
+
while (2 * i + 1 < heapSize) {
|
|
7616
|
+
const left = 2 * i + 1;
|
|
7617
|
+
const right = 2 * i + 2;
|
|
7618
|
+
if (right < heapSize) {
|
|
7619
|
+
path.push(left, right);
|
|
7620
|
+
} else {
|
|
7621
|
+
path.push(left);
|
|
7622
|
+
}
|
|
7623
|
+
i = left;
|
|
7624
|
+
}
|
|
7625
|
+
return path;
|
|
7626
|
+
};
|
|
7510
7627
|
if (heap.length === 0) {
|
|
7511
7628
|
steps.push({
|
|
7512
7629
|
operation: "poll",
|
|
@@ -7526,7 +7643,9 @@ function generateHeapSteps() {
|
|
|
7526
7643
|
description: `poll(): Remove min ${removed}, move last element ${last} to root`,
|
|
7527
7644
|
codeLine: 13,
|
|
7528
7645
|
variables: { removed, moved: last },
|
|
7529
|
-
highlightIndex: 0
|
|
7646
|
+
highlightIndex: 0,
|
|
7647
|
+
siftPath: getPathToLeaf(heap.length, 0),
|
|
7648
|
+
currentIndex: 0
|
|
7530
7649
|
});
|
|
7531
7650
|
let idx = 0;
|
|
7532
7651
|
while (true) {
|
|
@@ -7546,7 +7665,8 @@ function generateHeapSteps() {
|
|
|
7546
7665
|
description: `siftDown: ${heap[idx]} is smaller than children, heap property satisfied!`,
|
|
7547
7666
|
codeLine: 14,
|
|
7548
7667
|
variables: { index: idx, value: heap[idx] },
|
|
7549
|
-
highlightIndex: idx
|
|
7668
|
+
highlightIndex: idx,
|
|
7669
|
+
currentIndex: idx
|
|
7550
7670
|
});
|
|
7551
7671
|
break;
|
|
7552
7672
|
}
|
|
@@ -7560,7 +7680,9 @@ function generateHeapSteps() {
|
|
|
7560
7680
|
child: heap[smallestIdx],
|
|
7561
7681
|
childIdx: smallestIdx
|
|
7562
7682
|
},
|
|
7563
|
-
compareIndices: [idx, smallestIdx]
|
|
7683
|
+
compareIndices: [idx, smallestIdx],
|
|
7684
|
+
siftPath: [idx, leftIdx < heap.length ? leftIdx : -1, rightIdx < heap.length ? rightIdx : -1].filter((i) => i >= 0),
|
|
7685
|
+
currentIndex: idx
|
|
7564
7686
|
});
|
|
7565
7687
|
[heap[idx], heap[smallestIdx]] = [heap[smallestIdx], heap[idx]];
|
|
7566
7688
|
steps.push({
|
|
@@ -7570,7 +7692,8 @@ function generateHeapSteps() {
|
|
|
7570
7692
|
codeLine: 14,
|
|
7571
7693
|
variables: { index: smallestIdx },
|
|
7572
7694
|
swapIndices: [idx, smallestIdx],
|
|
7573
|
-
highlightIndex: smallestIdx
|
|
7695
|
+
highlightIndex: smallestIdx,
|
|
7696
|
+
currentIndex: smallestIdx
|
|
7574
7697
|
});
|
|
7575
7698
|
idx = smallestIdx;
|
|
7576
7699
|
}
|
|
@@ -7696,7 +7819,7 @@ const PriorityQueueVisualizerComponent = ({ showControls = true, showCode = true
|
|
|
7696
7819
|
heap: [],
|
|
7697
7820
|
description: ""
|
|
7698
7821
|
};
|
|
7699
|
-
const { heap, highlightIndex, swapIndices, compareIndices, description } = currentStepData;
|
|
7822
|
+
const { heap, highlightIndex, swapIndices, compareIndices, description, siftPath, currentIndex } = currentStepData;
|
|
7700
7823
|
const positions = getTreePositions(heap.length);
|
|
7701
7824
|
const getNodeStyle = (idx) => {
|
|
7702
7825
|
if (idx === highlightIndex) {
|
|
@@ -7708,11 +7831,25 @@ const PriorityQueueVisualizerComponent = ({ showControls = true, showCode = true
|
|
|
7708
7831
|
if (compareIndices == null ? void 0 : compareIndices.includes(idx)) {
|
|
7709
7832
|
return "fill-yellow-300 stroke-yellow-400";
|
|
7710
7833
|
}
|
|
7834
|
+
if ((siftPath == null ? void 0 : siftPath.includes(idx)) && idx !== currentIndex) {
|
|
7835
|
+
return "fill-purple-200 stroke-purple-400";
|
|
7836
|
+
}
|
|
7711
7837
|
if (idx === 0) {
|
|
7712
7838
|
return "fill-purple-100 stroke-purple-300";
|
|
7713
7839
|
}
|
|
7714
7840
|
return "fill-white stroke-gray-300";
|
|
7715
7841
|
};
|
|
7842
|
+
const isEdgeOnPath = (parentIdx, childIdx) => {
|
|
7843
|
+
if (!siftPath || siftPath.length < 2) return false;
|
|
7844
|
+
for (let i = 0; i < siftPath.length - 1; i++) {
|
|
7845
|
+
const a = siftPath[i];
|
|
7846
|
+
const b = siftPath[i + 1];
|
|
7847
|
+
if (a === parentIdx && b === childIdx || a === childIdx && b === parentIdx) {
|
|
7848
|
+
return true;
|
|
7849
|
+
}
|
|
7850
|
+
}
|
|
7851
|
+
return false;
|
|
7852
|
+
};
|
|
7716
7853
|
const getTextColor = (idx) => {
|
|
7717
7854
|
if (idx === highlightIndex || (swapIndices == null ? void 0 : swapIndices.includes(idx))) {
|
|
7718
7855
|
return "white";
|
|
@@ -7733,6 +7870,49 @@ const PriorityQueueVisualizerComponent = ({ showControls = true, showCode = true
|
|
|
7733
7870
|
] }) }) }),
|
|
7734
7871
|
/* @__PURE__ */ jsx("div", { className: "p-4", children: /* @__PURE__ */ jsxs("div", { className: `flex gap-4 ${showCode ? "flex-col lg:flex-row" : ""}`, children: [
|
|
7735
7872
|
/* @__PURE__ */ jsxs(VisualizationArea, { minHeight: 400, children: [
|
|
7873
|
+
/* @__PURE__ */ jsxs("div", { className: "mb-4 p-4 bg-gradient-to-r from-purple-50 to-pink-50 rounded-xl border-2 border-purple-200", children: [
|
|
7874
|
+
/* @__PURE__ */ jsxs("div", { className: "text-sm font-bold text-purple-800 mb-3 flex items-center gap-2", children: [
|
|
7875
|
+
/* @__PURE__ */ jsx("span", { className: "text-lg", children: "🏔️" }),
|
|
7876
|
+
" Min-Heap Property"
|
|
7877
|
+
] }),
|
|
7878
|
+
/* @__PURE__ */ jsxs("div", { className: "font-mono text-sm bg-white rounded-lg p-3 border border-purple-200", children: [
|
|
7879
|
+
/* @__PURE__ */ jsx("div", { className: "text-center text-purple-700 font-bold mb-2", children: "heap[parent] ≤ heap[children]" }),
|
|
7880
|
+
/* @__PURE__ */ jsxs("div", { className: "grid grid-cols-1 sm:grid-cols-3 gap-2 text-xs text-gray-600", children: [
|
|
7881
|
+
/* @__PURE__ */ jsxs("div", { className: "bg-purple-50 p-2 rounded text-center", children: [
|
|
7882
|
+
/* @__PURE__ */ jsx("span", { className: "font-semibold", children: "parent(i)" }),
|
|
7883
|
+
" = ⌊(i-1)/2⌋"
|
|
7884
|
+
] }),
|
|
7885
|
+
/* @__PURE__ */ jsxs("div", { className: "bg-purple-50 p-2 rounded text-center", children: [
|
|
7886
|
+
/* @__PURE__ */ jsx("span", { className: "font-semibold", children: "left(i)" }),
|
|
7887
|
+
" = 2i + 1"
|
|
7888
|
+
] }),
|
|
7889
|
+
/* @__PURE__ */ jsxs("div", { className: "bg-purple-50 p-2 rounded text-center", children: [
|
|
7890
|
+
/* @__PURE__ */ jsx("span", { className: "font-semibold", children: "right(i)" }),
|
|
7891
|
+
" = 2i + 2"
|
|
7892
|
+
] })
|
|
7893
|
+
] })
|
|
7894
|
+
] }),
|
|
7895
|
+
currentIndex !== void 0 && currentIndex >= 0 && /* @__PURE__ */ jsx("div", { className: "mt-3 p-2 bg-white rounded-lg border border-purple-200", children: /* @__PURE__ */ jsxs("div", { className: "text-xs text-gray-600 text-center", children: [
|
|
7896
|
+
/* @__PURE__ */ jsxs("span", { className: "font-semibold text-purple-700", children: [
|
|
7897
|
+
"Current: i = ",
|
|
7898
|
+
currentIndex
|
|
7899
|
+
] }),
|
|
7900
|
+
currentIndex > 0 && /* @__PURE__ */ jsxs("span", { className: "mx-2", children: [
|
|
7901
|
+
"→ parent(",
|
|
7902
|
+
currentIndex,
|
|
7903
|
+
") = ⌊(",
|
|
7904
|
+
currentIndex,
|
|
7905
|
+
"-1)/2⌋ = ",
|
|
7906
|
+
/* @__PURE__ */ jsx("span", { className: "text-purple-600 font-bold", children: Math.floor((currentIndex - 1) / 2) })
|
|
7907
|
+
] }),
|
|
7908
|
+
2 * currentIndex + 1 < heap.length && /* @__PURE__ */ jsxs("span", { className: "mx-2", children: [
|
|
7909
|
+
"→ left(",
|
|
7910
|
+
currentIndex,
|
|
7911
|
+
") = ",
|
|
7912
|
+
/* @__PURE__ */ jsx("span", { className: "text-purple-600 font-bold", children: 2 * currentIndex + 1 })
|
|
7913
|
+
] })
|
|
7914
|
+
] }) })
|
|
7915
|
+
] }),
|
|
7736
7916
|
/* @__PURE__ */ jsxs("div", { className: "mb-4", children: [
|
|
7737
7917
|
/* @__PURE__ */ jsx("div", { className: "text-sm font-medium text-gray-700 mb-2", children: "Binary Heap Structure" }),
|
|
7738
7918
|
/* @__PURE__ */ jsx("div", { className: "bg-gray-50 rounded-lg p-2 overflow-x-auto", children: heap.length > 0 ? /* @__PURE__ */ jsxs(
|
|
@@ -7749,6 +7929,7 @@ const PriorityQueueVisualizerComponent = ({ showControls = true, showCode = true
|
|
|
7749
7929
|
const childPos = positions[idx];
|
|
7750
7930
|
if (!parentPos || !childPos) return null;
|
|
7751
7931
|
const isHighlighted = (compareIndices == null ? void 0 : compareIndices.includes(idx)) && (compareIndices == null ? void 0 : compareIndices.includes(parentIdx)) || (swapIndices == null ? void 0 : swapIndices.includes(idx)) && (swapIndices == null ? void 0 : swapIndices.includes(parentIdx));
|
|
7932
|
+
const isOnPath = isEdgeOnPath(parentIdx, idx);
|
|
7752
7933
|
return /* @__PURE__ */ jsx(
|
|
7753
7934
|
"line",
|
|
7754
7935
|
{
|
|
@@ -7756,8 +7937,9 @@ const PriorityQueueVisualizerComponent = ({ showControls = true, showCode = true
|
|
|
7756
7937
|
y1: parentPos.y,
|
|
7757
7938
|
x2: childPos.x,
|
|
7758
7939
|
y2: childPos.y,
|
|
7759
|
-
stroke: isHighlighted ? "#a855f7" : "#d1d5db",
|
|
7760
|
-
strokeWidth: isHighlighted ? 2 : 1
|
|
7940
|
+
stroke: isHighlighted ? "#a855f7" : isOnPath ? "#c4b5fd" : "#d1d5db",
|
|
7941
|
+
strokeWidth: isHighlighted ? 3 : isOnPath ? 2 : 1,
|
|
7942
|
+
strokeDasharray: isOnPath && !isHighlighted ? "4,2" : void 0
|
|
7761
7943
|
},
|
|
7762
7944
|
`edge-${idx}`
|
|
7763
7945
|
);
|
|
@@ -7774,7 +7956,7 @@ const PriorityQueueVisualizerComponent = ({ showControls = true, showCode = true
|
|
|
7774
7956
|
"circle",
|
|
7775
7957
|
{
|
|
7776
7958
|
r: "18",
|
|
7777
|
-
className: `${getNodeStyle(idx)} stroke-2 transition-
|
|
7959
|
+
className: `${getNodeStyle(idx)} stroke-2 transition-colors`
|
|
7778
7960
|
}
|
|
7779
7961
|
),
|
|
7780
7962
|
/* @__PURE__ */ jsx(
|