linked list visualisations
This commit is contained in:
@@ -0,0 +1,389 @@
|
||||
import type { AlgorithmDefinition } from '@/lib/visualizations/types';
|
||||
|
||||
export const fastSlowPointersAlgorithm: AlgorithmDefinition = {
|
||||
id: 'fast-slow-pointers',
|
||||
title: 'Find Middle of Linked List',
|
||||
slug: 'fast-slow-pointers',
|
||||
pattern: {
|
||||
name: 'Fast & Slow Pointers',
|
||||
description: 'Use two pointers moving at different speeds to find cycle or middle',
|
||||
},
|
||||
problemStatement:
|
||||
'Given a linked list, find the middle node. If there are two middle nodes, return the second one.',
|
||||
intuition:
|
||||
'If fast pointer moves twice as fast as slow, when fast reaches the end, slow will be at the middle.',
|
||||
code: {
|
||||
language: 'python',
|
||||
code: `def find_middle(head):
|
||||
slow = fast = head
|
||||
|
||||
while fast and fast.next:
|
||||
slow = slow.next
|
||||
fast = fast.next.next
|
||||
|
||||
return slow`,
|
||||
},
|
||||
steps: [
|
||||
// Problem phase
|
||||
{
|
||||
id: 'step-1',
|
||||
phase: 'problem',
|
||||
explanation: 'We have a linked list: 1 → 2 → 3 → 4 → 5 → null. Find the middle node.',
|
||||
dataState: {
|
||||
arrays: [],
|
||||
pointers: [],
|
||||
variables: [],
|
||||
calculations: [],
|
||||
linkedLists: [
|
||||
{
|
||||
id: 'list',
|
||||
nodes: [
|
||||
{ id: 'n1', value: 1, index: 0, state: 'normal' },
|
||||
{ id: 'n2', value: 2, index: 1, state: 'normal' },
|
||||
{ id: 'n3', value: 3, index: 2, state: 'normal' },
|
||||
{ id: 'n4', value: 4, index: 3, state: 'normal' },
|
||||
{ id: 'n5', value: 5, index: 4, state: 'normal' },
|
||||
{ id: 'null', value: 0, index: 5, state: 'normal', isNull: true },
|
||||
],
|
||||
},
|
||||
],
|
||||
linkedListPointers: [],
|
||||
},
|
||||
},
|
||||
// Intuition phase
|
||||
{
|
||||
id: 'step-2',
|
||||
phase: 'intuition',
|
||||
explanation:
|
||||
'The key insight: if one pointer moves 2x faster than another, when the fast one finishes, the slow one is halfway.',
|
||||
dataState: {
|
||||
arrays: [],
|
||||
pointers: [],
|
||||
variables: [],
|
||||
calculations: [],
|
||||
linkedLists: [
|
||||
{
|
||||
id: 'list',
|
||||
nodes: [
|
||||
{ id: 'n1', value: 1, index: 0, state: 'normal' },
|
||||
{ id: 'n2', value: 2, index: 1, state: 'normal' },
|
||||
{ id: 'n3', value: 3, index: 2, state: 'highlighted' },
|
||||
{ id: 'n4', value: 4, index: 3, state: 'normal' },
|
||||
{ id: 'n5', value: 5, index: 4, state: 'normal' },
|
||||
{ id: 'null', value: 0, index: 5, state: 'normal', isNull: true },
|
||||
],
|
||||
},
|
||||
],
|
||||
linkedListPointers: [],
|
||||
},
|
||||
},
|
||||
// Code phase
|
||||
{
|
||||
id: 'step-3',
|
||||
phase: 'code',
|
||||
explanation: 'Initialize both pointers at the head of the list.',
|
||||
codeLine: 2,
|
||||
dataState: {
|
||||
arrays: [],
|
||||
pointers: [],
|
||||
variables: [
|
||||
{ id: 'slow', name: 'slow', value: 'head' },
|
||||
{ id: 'fast', name: 'fast', value: 'head' },
|
||||
],
|
||||
calculations: [],
|
||||
linkedLists: [
|
||||
{
|
||||
id: 'list',
|
||||
nodes: [
|
||||
{ id: 'n1', value: 1, index: 0, state: 'highlighted' },
|
||||
{ id: 'n2', value: 2, index: 1, state: 'normal' },
|
||||
{ id: 'n3', value: 3, index: 2, state: 'normal' },
|
||||
{ id: 'n4', value: 4, index: 3, state: 'normal' },
|
||||
{ id: 'n5', value: 5, index: 4, state: 'normal' },
|
||||
{ id: 'null', value: 0, index: 5, state: 'normal', isNull: true },
|
||||
],
|
||||
},
|
||||
],
|
||||
linkedListPointers: [
|
||||
{ id: 'slow', name: 'slow', nodeIndex: 0, color: 'slow' },
|
||||
{ id: 'fast', name: 'fast', nodeIndex: 0, color: 'fast' },
|
||||
],
|
||||
},
|
||||
},
|
||||
// Execution phase - iteration 1
|
||||
{
|
||||
id: 'step-4',
|
||||
phase: 'execution',
|
||||
explanation: 'Check: fast (node 1) exists and fast.next (node 2) exists. Enter loop.',
|
||||
codeLine: 4,
|
||||
decision: {
|
||||
question: 'Is fast and fast.next valid?',
|
||||
answer: 'Yes, both exist',
|
||||
action: 'Enter the while loop',
|
||||
},
|
||||
dataState: {
|
||||
arrays: [],
|
||||
pointers: [],
|
||||
variables: [
|
||||
{ id: 'slow', name: 'slow', value: 'node 1' },
|
||||
{ id: 'fast', name: 'fast', value: 'node 1' },
|
||||
],
|
||||
calculations: [],
|
||||
linkedLists: [
|
||||
{
|
||||
id: 'list',
|
||||
nodes: [
|
||||
{ id: 'n1', value: 1, index: 0, state: 'highlighted' },
|
||||
{ id: 'n2', value: 2, index: 1, state: 'normal' },
|
||||
{ id: 'n3', value: 3, index: 2, state: 'normal' },
|
||||
{ id: 'n4', value: 4, index: 3, state: 'normal' },
|
||||
{ id: 'n5', value: 5, index: 4, state: 'normal' },
|
||||
{ id: 'null', value: 0, index: 5, state: 'normal', isNull: true },
|
||||
],
|
||||
},
|
||||
],
|
||||
linkedListPointers: [
|
||||
{ id: 'slow', name: 'slow', nodeIndex: 0, color: 'slow' },
|
||||
{ id: 'fast', name: 'fast', nodeIndex: 0, color: 'fast' },
|
||||
],
|
||||
},
|
||||
},
|
||||
{
|
||||
id: 'step-5',
|
||||
phase: 'execution',
|
||||
explanation: 'Move slow one step forward (1 → 2).',
|
||||
codeLine: 5,
|
||||
dataState: {
|
||||
arrays: [],
|
||||
pointers: [],
|
||||
variables: [
|
||||
{ id: 'slow', name: 'slow', value: 'node 2', previousValue: 'node 1' },
|
||||
{ id: 'fast', name: 'fast', value: 'node 1' },
|
||||
],
|
||||
calculations: [],
|
||||
linkedLists: [
|
||||
{
|
||||
id: 'list',
|
||||
nodes: [
|
||||
{ id: 'n1', value: 1, index: 0, state: 'dimmed' },
|
||||
{ id: 'n2', value: 2, index: 1, state: 'highlighted' },
|
||||
{ id: 'n3', value: 3, index: 2, state: 'normal' },
|
||||
{ id: 'n4', value: 4, index: 3, state: 'normal' },
|
||||
{ id: 'n5', value: 5, index: 4, state: 'normal' },
|
||||
{ id: 'null', value: 0, index: 5, state: 'normal', isNull: true },
|
||||
],
|
||||
},
|
||||
],
|
||||
linkedListPointers: [
|
||||
{ id: 'slow', name: 'slow', nodeIndex: 1, color: 'slow' },
|
||||
{ id: 'fast', name: 'fast', nodeIndex: 0, color: 'fast' },
|
||||
],
|
||||
},
|
||||
},
|
||||
{
|
||||
id: 'step-6',
|
||||
phase: 'execution',
|
||||
explanation: 'Move fast two steps forward (1 → 2 → 3).',
|
||||
codeLine: 6,
|
||||
dataState: {
|
||||
arrays: [],
|
||||
pointers: [],
|
||||
variables: [
|
||||
{ id: 'slow', name: 'slow', value: 'node 2' },
|
||||
{ id: 'fast', name: 'fast', value: 'node 3', previousValue: 'node 1' },
|
||||
],
|
||||
calculations: [],
|
||||
linkedLists: [
|
||||
{
|
||||
id: 'list',
|
||||
nodes: [
|
||||
{ id: 'n1', value: 1, index: 0, state: 'dimmed' },
|
||||
{ id: 'n2', value: 2, index: 1, state: 'highlighted' },
|
||||
{ id: 'n3', value: 3, index: 2, state: 'comparing' },
|
||||
{ id: 'n4', value: 4, index: 3, state: 'normal' },
|
||||
{ id: 'n5', value: 5, index: 4, state: 'normal' },
|
||||
{ id: 'null', value: 0, index: 5, state: 'normal', isNull: true },
|
||||
],
|
||||
},
|
||||
],
|
||||
linkedListPointers: [
|
||||
{ id: 'slow', name: 'slow', nodeIndex: 1, color: 'slow' },
|
||||
{ id: 'fast', name: 'fast', nodeIndex: 2, color: 'fast' },
|
||||
],
|
||||
},
|
||||
},
|
||||
// Iteration 2
|
||||
{
|
||||
id: 'step-7',
|
||||
phase: 'execution',
|
||||
explanation: 'Check: fast (node 3) exists and fast.next (node 4) exists. Continue loop.',
|
||||
codeLine: 4,
|
||||
decision: {
|
||||
question: 'Is fast and fast.next valid?',
|
||||
answer: 'Yes, both exist',
|
||||
action: 'Continue the while loop',
|
||||
},
|
||||
dataState: {
|
||||
arrays: [],
|
||||
pointers: [],
|
||||
variables: [
|
||||
{ id: 'slow', name: 'slow', value: 'node 2' },
|
||||
{ id: 'fast', name: 'fast', value: 'node 3' },
|
||||
],
|
||||
calculations: [],
|
||||
linkedLists: [
|
||||
{
|
||||
id: 'list',
|
||||
nodes: [
|
||||
{ id: 'n1', value: 1, index: 0, state: 'dimmed' },
|
||||
{ id: 'n2', value: 2, index: 1, state: 'highlighted' },
|
||||
{ id: 'n3', value: 3, index: 2, state: 'comparing' },
|
||||
{ id: 'n4', value: 4, index: 3, state: 'normal' },
|
||||
{ id: 'n5', value: 5, index: 4, state: 'normal' },
|
||||
{ id: 'null', value: 0, index: 5, state: 'normal', isNull: true },
|
||||
],
|
||||
},
|
||||
],
|
||||
linkedListPointers: [
|
||||
{ id: 'slow', name: 'slow', nodeIndex: 1, color: 'slow' },
|
||||
{ id: 'fast', name: 'fast', nodeIndex: 2, color: 'fast' },
|
||||
],
|
||||
},
|
||||
},
|
||||
{
|
||||
id: 'step-8',
|
||||
phase: 'execution',
|
||||
explanation: 'Move slow one step forward (2 → 3).',
|
||||
codeLine: 5,
|
||||
dataState: {
|
||||
arrays: [],
|
||||
pointers: [],
|
||||
variables: [
|
||||
{ id: 'slow', name: 'slow', value: 'node 3', previousValue: 'node 2' },
|
||||
{ id: 'fast', name: 'fast', value: 'node 3' },
|
||||
],
|
||||
calculations: [],
|
||||
linkedLists: [
|
||||
{
|
||||
id: 'list',
|
||||
nodes: [
|
||||
{ id: 'n1', value: 1, index: 0, state: 'dimmed' },
|
||||
{ id: 'n2', value: 2, index: 1, state: 'dimmed' },
|
||||
{ id: 'n3', value: 3, index: 2, state: 'highlighted' },
|
||||
{ id: 'n4', value: 4, index: 3, state: 'normal' },
|
||||
{ id: 'n5', value: 5, index: 4, state: 'normal' },
|
||||
{ id: 'null', value: 0, index: 5, state: 'normal', isNull: true },
|
||||
],
|
||||
},
|
||||
],
|
||||
linkedListPointers: [
|
||||
{ id: 'slow', name: 'slow', nodeIndex: 2, color: 'slow' },
|
||||
{ id: 'fast', name: 'fast', nodeIndex: 2, color: 'fast' },
|
||||
],
|
||||
},
|
||||
},
|
||||
{
|
||||
id: 'step-9',
|
||||
phase: 'execution',
|
||||
explanation: 'Move fast two steps forward (3 → 4 → 5).',
|
||||
codeLine: 6,
|
||||
dataState: {
|
||||
arrays: [],
|
||||
pointers: [],
|
||||
variables: [
|
||||
{ id: 'slow', name: 'slow', value: 'node 3' },
|
||||
{ id: 'fast', name: 'fast', value: 'node 5', previousValue: 'node 3' },
|
||||
],
|
||||
calculations: [],
|
||||
linkedLists: [
|
||||
{
|
||||
id: 'list',
|
||||
nodes: [
|
||||
{ id: 'n1', value: 1, index: 0, state: 'dimmed' },
|
||||
{ id: 'n2', value: 2, index: 1, state: 'dimmed' },
|
||||
{ id: 'n3', value: 3, index: 2, state: 'highlighted' },
|
||||
{ id: 'n4', value: 4, index: 3, state: 'dimmed' },
|
||||
{ id: 'n5', value: 5, index: 4, state: 'comparing' },
|
||||
{ id: 'null', value: 0, index: 5, state: 'normal', isNull: true },
|
||||
],
|
||||
},
|
||||
],
|
||||
linkedListPointers: [
|
||||
{ id: 'slow', name: 'slow', nodeIndex: 2, color: 'slow' },
|
||||
{ id: 'fast', name: 'fast', nodeIndex: 4, color: 'fast' },
|
||||
],
|
||||
},
|
||||
},
|
||||
// Check and exit
|
||||
{
|
||||
id: 'step-10',
|
||||
phase: 'execution',
|
||||
explanation: 'Check: fast (node 5) exists but fast.next is null. Exit loop.',
|
||||
codeLine: 4,
|
||||
decision: {
|
||||
question: 'Is fast and fast.next valid?',
|
||||
answer: 'No, fast.next is null',
|
||||
action: 'Exit the while loop',
|
||||
},
|
||||
dataState: {
|
||||
arrays: [],
|
||||
pointers: [],
|
||||
variables: [
|
||||
{ id: 'slow', name: 'slow', value: 'node 3' },
|
||||
{ id: 'fast', name: 'fast', value: 'node 5' },
|
||||
],
|
||||
calculations: [],
|
||||
linkedLists: [
|
||||
{
|
||||
id: 'list',
|
||||
nodes: [
|
||||
{ id: 'n1', value: 1, index: 0, state: 'dimmed' },
|
||||
{ id: 'n2', value: 2, index: 1, state: 'dimmed' },
|
||||
{ id: 'n3', value: 3, index: 2, state: 'highlighted' },
|
||||
{ id: 'n4', value: 4, index: 3, state: 'dimmed' },
|
||||
{ id: 'n5', value: 5, index: 4, state: 'comparing' },
|
||||
{ id: 'null', value: 0, index: 5, state: 'normal', isNull: true },
|
||||
],
|
||||
},
|
||||
],
|
||||
linkedListPointers: [
|
||||
{ id: 'slow', name: 'slow', nodeIndex: 2, color: 'slow' },
|
||||
{ id: 'fast', name: 'fast', nodeIndex: 4, color: 'fast' },
|
||||
],
|
||||
},
|
||||
},
|
||||
// Return result
|
||||
{
|
||||
id: 'step-11',
|
||||
phase: 'execution',
|
||||
explanation: 'Return slow, which points to node 3 — the middle of the linked list!',
|
||||
codeLine: 8,
|
||||
dataState: {
|
||||
arrays: [],
|
||||
pointers: [],
|
||||
variables: [
|
||||
{ id: 'slow', name: 'slow', value: 'node 3' },
|
||||
{ id: 'fast', name: 'fast', value: 'node 5' },
|
||||
{ id: 'result', name: 'result', value: 3 },
|
||||
],
|
||||
calculations: [],
|
||||
linkedLists: [
|
||||
{
|
||||
id: 'list',
|
||||
nodes: [
|
||||
{ id: 'n1', value: 1, index: 0, state: 'dimmed' },
|
||||
{ id: 'n2', value: 2, index: 1, state: 'dimmed' },
|
||||
{ id: 'n3', value: 3, index: 2, state: 'success' },
|
||||
{ id: 'n4', value: 4, index: 3, state: 'dimmed' },
|
||||
{ id: 'n5', value: 5, index: 4, state: 'dimmed' },
|
||||
{ id: 'null', value: 0, index: 5, state: 'normal', isNull: true },
|
||||
],
|
||||
},
|
||||
],
|
||||
linkedListPointers: [
|
||||
{ id: 'slow', name: 'slow', nodeIndex: 2, color: 'slow' },
|
||||
],
|
||||
},
|
||||
},
|
||||
],
|
||||
};
|
||||
@@ -0,0 +1,515 @@
|
||||
import type { AlgorithmDefinition } from '@/lib/visualizations/types';
|
||||
|
||||
export const linkedListReversalAlgorithm: AlgorithmDefinition = {
|
||||
id: 'linkedlist-reversal',
|
||||
title: 'Reverse a Linked List',
|
||||
slug: 'linkedlist-reversal',
|
||||
pattern: {
|
||||
name: 'LinkedList Reversal',
|
||||
description: 'Reverse links between nodes using three pointers',
|
||||
},
|
||||
problemStatement:
|
||||
'Given a singly linked list, reverse it in-place and return the new head.',
|
||||
intuition:
|
||||
'Use three pointers (prev, curr, next) to reverse each link. Save next before breaking the link, then move forward.',
|
||||
code: {
|
||||
language: 'python',
|
||||
code: `def reverse_list(head):
|
||||
prev = None
|
||||
curr = head
|
||||
|
||||
while curr:
|
||||
next_node = curr.next
|
||||
curr.next = prev
|
||||
prev = curr
|
||||
curr = next_node
|
||||
|
||||
return prev`,
|
||||
},
|
||||
steps: [
|
||||
// Problem phase
|
||||
{
|
||||
id: 'step-1',
|
||||
phase: 'problem',
|
||||
explanation: 'We have a linked list: 1 → 2 → 3 → 4 → null. Reverse it to get 4 → 3 → 2 → 1 → null.',
|
||||
dataState: {
|
||||
arrays: [],
|
||||
pointers: [],
|
||||
variables: [],
|
||||
calculations: [],
|
||||
linkedLists: [
|
||||
{
|
||||
id: 'list',
|
||||
nodes: [
|
||||
{ id: 'n1', value: 1, index: 0, state: 'normal' },
|
||||
{ id: 'n2', value: 2, index: 1, state: 'normal' },
|
||||
{ id: 'n3', value: 3, index: 2, state: 'normal' },
|
||||
{ id: 'n4', value: 4, index: 3, state: 'normal' },
|
||||
{ id: 'null', value: 0, index: 4, state: 'normal', isNull: true },
|
||||
],
|
||||
},
|
||||
],
|
||||
linkedListPointers: [],
|
||||
},
|
||||
},
|
||||
// Intuition phase
|
||||
{
|
||||
id: 'step-2',
|
||||
phase: 'intuition',
|
||||
explanation:
|
||||
'Key insight: We need to reverse each arrow. To do this safely, save the next node before changing the link.',
|
||||
dataState: {
|
||||
arrays: [],
|
||||
pointers: [],
|
||||
variables: [],
|
||||
calculations: [],
|
||||
linkedLists: [
|
||||
{
|
||||
id: 'list',
|
||||
nodes: [
|
||||
{ id: 'n1', value: 1, index: 0, state: 'highlighted' },
|
||||
{ id: 'n2', value: 2, index: 1, state: 'comparing' },
|
||||
{ id: 'n3', value: 3, index: 2, state: 'normal' },
|
||||
{ id: 'n4', value: 4, index: 3, state: 'normal' },
|
||||
{ id: 'null', value: 0, index: 4, state: 'normal', isNull: true },
|
||||
],
|
||||
},
|
||||
],
|
||||
linkedListPointers: [],
|
||||
},
|
||||
},
|
||||
// Code phase - initialization
|
||||
{
|
||||
id: 'step-3',
|
||||
phase: 'code',
|
||||
explanation: 'Initialize prev = None (nothing before head yet) and curr = head.',
|
||||
codeLine: 2,
|
||||
codeHighlightLines: [2, 3],
|
||||
dataState: {
|
||||
arrays: [],
|
||||
pointers: [],
|
||||
variables: [
|
||||
{ id: 'prev', name: 'prev', value: 'None' },
|
||||
{ id: 'curr', name: 'curr', value: 'node 1' },
|
||||
],
|
||||
calculations: [],
|
||||
linkedLists: [
|
||||
{
|
||||
id: 'list',
|
||||
nodes: [
|
||||
{ id: 'n1', value: 1, index: 0, state: 'highlighted' },
|
||||
{ id: 'n2', value: 2, index: 1, state: 'normal' },
|
||||
{ id: 'n3', value: 3, index: 2, state: 'normal' },
|
||||
{ id: 'n4', value: 4, index: 3, state: 'normal' },
|
||||
{ id: 'null', value: 0, index: 4, state: 'normal', isNull: true },
|
||||
],
|
||||
},
|
||||
],
|
||||
linkedListPointers: [
|
||||
{ id: 'curr', name: 'curr', nodeIndex: 0, color: 'curr' },
|
||||
],
|
||||
},
|
||||
},
|
||||
// Execution - iteration 1
|
||||
{
|
||||
id: 'step-4',
|
||||
phase: 'execution',
|
||||
explanation: 'Check: curr (node 1) exists. Enter the while loop.',
|
||||
codeLine: 5,
|
||||
decision: {
|
||||
question: 'Is curr not None?',
|
||||
answer: 'Yes, curr is node 1',
|
||||
action: 'Enter the while loop',
|
||||
},
|
||||
dataState: {
|
||||
arrays: [],
|
||||
pointers: [],
|
||||
variables: [
|
||||
{ id: 'prev', name: 'prev', value: 'None' },
|
||||
{ id: 'curr', name: 'curr', value: 'node 1' },
|
||||
],
|
||||
calculations: [],
|
||||
linkedLists: [
|
||||
{
|
||||
id: 'list',
|
||||
nodes: [
|
||||
{ id: 'n1', value: 1, index: 0, state: 'highlighted' },
|
||||
{ id: 'n2', value: 2, index: 1, state: 'normal' },
|
||||
{ id: 'n3', value: 3, index: 2, state: 'normal' },
|
||||
{ id: 'n4', value: 4, index: 3, state: 'normal' },
|
||||
{ id: 'null', value: 0, index: 4, state: 'normal', isNull: true },
|
||||
],
|
||||
},
|
||||
],
|
||||
linkedListPointers: [
|
||||
{ id: 'curr', name: 'curr', nodeIndex: 0, color: 'curr' },
|
||||
],
|
||||
},
|
||||
},
|
||||
{
|
||||
id: 'step-5',
|
||||
phase: 'execution',
|
||||
explanation: 'Save next_node = curr.next (node 2). This preserves our forward reference.',
|
||||
codeLine: 6,
|
||||
dataState: {
|
||||
arrays: [],
|
||||
pointers: [],
|
||||
variables: [
|
||||
{ id: 'prev', name: 'prev', value: 'None' },
|
||||
{ id: 'curr', name: 'curr', value: 'node 1' },
|
||||
{ id: 'next', name: 'next', value: 'node 2' },
|
||||
],
|
||||
calculations: [],
|
||||
linkedLists: [
|
||||
{
|
||||
id: 'list',
|
||||
nodes: [
|
||||
{ id: 'n1', value: 1, index: 0, state: 'highlighted' },
|
||||
{ id: 'n2', value: 2, index: 1, state: 'comparing' },
|
||||
{ id: 'n3', value: 3, index: 2, state: 'normal' },
|
||||
{ id: 'n4', value: 4, index: 3, state: 'normal' },
|
||||
{ id: 'null', value: 0, index: 4, state: 'normal', isNull: true },
|
||||
],
|
||||
},
|
||||
],
|
||||
linkedListPointers: [
|
||||
{ id: 'curr', name: 'curr', nodeIndex: 0, color: 'curr' },
|
||||
{ id: 'next', name: 'next', nodeIndex: 1, color: 'next' },
|
||||
],
|
||||
},
|
||||
},
|
||||
{
|
||||
id: 'step-6',
|
||||
phase: 'execution',
|
||||
explanation: 'Reverse the link: curr.next = prev. Node 1 now points to None (backwards!).',
|
||||
codeLine: 7,
|
||||
dataState: {
|
||||
arrays: [],
|
||||
pointers: [],
|
||||
variables: [
|
||||
{ id: 'prev', name: 'prev', value: 'None' },
|
||||
{ id: 'curr', name: 'curr', value: 'node 1' },
|
||||
{ id: 'next', name: 'next', value: 'node 2' },
|
||||
],
|
||||
calculations: [],
|
||||
linkedLists: [
|
||||
{
|
||||
id: 'list',
|
||||
nodes: [
|
||||
{ id: 'n1', value: 1, index: 0, state: 'success' },
|
||||
{ id: 'n2', value: 2, index: 1, state: 'comparing' },
|
||||
{ id: 'n3', value: 3, index: 2, state: 'normal' },
|
||||
{ id: 'n4', value: 4, index: 3, state: 'normal' },
|
||||
{ id: 'null', value: 0, index: 4, state: 'normal', isNull: true },
|
||||
],
|
||||
},
|
||||
],
|
||||
linkedListPointers: [
|
||||
{ id: 'curr', name: 'curr', nodeIndex: 0, color: 'curr' },
|
||||
{ id: 'next', name: 'next', nodeIndex: 1, color: 'next' },
|
||||
],
|
||||
},
|
||||
},
|
||||
{
|
||||
id: 'step-7',
|
||||
phase: 'execution',
|
||||
explanation: 'Move prev forward: prev = curr. Now prev points to node 1.',
|
||||
codeLine: 8,
|
||||
dataState: {
|
||||
arrays: [],
|
||||
pointers: [],
|
||||
variables: [
|
||||
{ id: 'prev', name: 'prev', value: 'node 1', previousValue: 'None' },
|
||||
{ id: 'curr', name: 'curr', value: 'node 1' },
|
||||
{ id: 'next', name: 'next', value: 'node 2' },
|
||||
],
|
||||
calculations: [],
|
||||
linkedLists: [
|
||||
{
|
||||
id: 'list',
|
||||
nodes: [
|
||||
{ id: 'n1', value: 1, index: 0, state: 'success' },
|
||||
{ id: 'n2', value: 2, index: 1, state: 'comparing' },
|
||||
{ id: 'n3', value: 3, index: 2, state: 'normal' },
|
||||
{ id: 'n4', value: 4, index: 3, state: 'normal' },
|
||||
{ id: 'null', value: 0, index: 4, state: 'normal', isNull: true },
|
||||
],
|
||||
},
|
||||
],
|
||||
linkedListPointers: [
|
||||
{ id: 'prev', name: 'prev', nodeIndex: 0, color: 'prev' },
|
||||
{ id: 'curr', name: 'curr', nodeIndex: 0, color: 'curr' },
|
||||
{ id: 'next', name: 'next', nodeIndex: 1, color: 'next' },
|
||||
],
|
||||
},
|
||||
},
|
||||
{
|
||||
id: 'step-8',
|
||||
phase: 'execution',
|
||||
explanation: 'Move curr forward: curr = next_node. Now curr points to node 2.',
|
||||
codeLine: 9,
|
||||
dataState: {
|
||||
arrays: [],
|
||||
pointers: [],
|
||||
variables: [
|
||||
{ id: 'prev', name: 'prev', value: 'node 1' },
|
||||
{ id: 'curr', name: 'curr', value: 'node 2', previousValue: 'node 1' },
|
||||
{ id: 'next', name: 'next', value: 'node 2' },
|
||||
],
|
||||
calculations: [],
|
||||
linkedLists: [
|
||||
{
|
||||
id: 'list',
|
||||
nodes: [
|
||||
{ id: 'n1', value: 1, index: 0, state: 'success' },
|
||||
{ id: 'n2', value: 2, index: 1, state: 'highlighted' },
|
||||
{ id: 'n3', value: 3, index: 2, state: 'normal' },
|
||||
{ id: 'n4', value: 4, index: 3, state: 'normal' },
|
||||
{ id: 'null', value: 0, index: 4, state: 'normal', isNull: true },
|
||||
],
|
||||
},
|
||||
],
|
||||
linkedListPointers: [
|
||||
{ id: 'prev', name: 'prev', nodeIndex: 0, color: 'prev' },
|
||||
{ id: 'curr', name: 'curr', nodeIndex: 1, color: 'curr' },
|
||||
],
|
||||
},
|
||||
},
|
||||
// Iteration 2
|
||||
{
|
||||
id: 'step-9',
|
||||
phase: 'execution',
|
||||
explanation: 'Check: curr (node 2) exists. Continue loop.',
|
||||
codeLine: 5,
|
||||
decision: {
|
||||
question: 'Is curr not None?',
|
||||
answer: 'Yes, curr is node 2',
|
||||
action: 'Continue the while loop',
|
||||
},
|
||||
dataState: {
|
||||
arrays: [],
|
||||
pointers: [],
|
||||
variables: [
|
||||
{ id: 'prev', name: 'prev', value: 'node 1' },
|
||||
{ id: 'curr', name: 'curr', value: 'node 2' },
|
||||
],
|
||||
calculations: [],
|
||||
linkedLists: [
|
||||
{
|
||||
id: 'list',
|
||||
nodes: [
|
||||
{ id: 'n1', value: 1, index: 0, state: 'success' },
|
||||
{ id: 'n2', value: 2, index: 1, state: 'highlighted' },
|
||||
{ id: 'n3', value: 3, index: 2, state: 'normal' },
|
||||
{ id: 'n4', value: 4, index: 3, state: 'normal' },
|
||||
{ id: 'null', value: 0, index: 4, state: 'normal', isNull: true },
|
||||
],
|
||||
},
|
||||
],
|
||||
linkedListPointers: [
|
||||
{ id: 'prev', name: 'prev', nodeIndex: 0, color: 'prev' },
|
||||
{ id: 'curr', name: 'curr', nodeIndex: 1, color: 'curr' },
|
||||
],
|
||||
},
|
||||
},
|
||||
{
|
||||
id: 'step-10',
|
||||
phase: 'execution',
|
||||
explanation: 'Save next_node = curr.next (node 3).',
|
||||
codeLine: 6,
|
||||
dataState: {
|
||||
arrays: [],
|
||||
pointers: [],
|
||||
variables: [
|
||||
{ id: 'prev', name: 'prev', value: 'node 1' },
|
||||
{ id: 'curr', name: 'curr', value: 'node 2' },
|
||||
{ id: 'next', name: 'next', value: 'node 3' },
|
||||
],
|
||||
calculations: [],
|
||||
linkedLists: [
|
||||
{
|
||||
id: 'list',
|
||||
nodes: [
|
||||
{ id: 'n1', value: 1, index: 0, state: 'success' },
|
||||
{ id: 'n2', value: 2, index: 1, state: 'highlighted' },
|
||||
{ id: 'n3', value: 3, index: 2, state: 'comparing' },
|
||||
{ id: 'n4', value: 4, index: 3, state: 'normal' },
|
||||
{ id: 'null', value: 0, index: 4, state: 'normal', isNull: true },
|
||||
],
|
||||
},
|
||||
],
|
||||
linkedListPointers: [
|
||||
{ id: 'prev', name: 'prev', nodeIndex: 0, color: 'prev' },
|
||||
{ id: 'curr', name: 'curr', nodeIndex: 1, color: 'curr' },
|
||||
{ id: 'next', name: 'next', nodeIndex: 2, color: 'next' },
|
||||
],
|
||||
},
|
||||
},
|
||||
{
|
||||
id: 'step-11',
|
||||
phase: 'execution',
|
||||
explanation: 'Reverse the link: curr.next = prev. Node 2 now points to node 1.',
|
||||
codeLine: 7,
|
||||
dataState: {
|
||||
arrays: [],
|
||||
pointers: [],
|
||||
variables: [
|
||||
{ id: 'prev', name: 'prev', value: 'node 1' },
|
||||
{ id: 'curr', name: 'curr', value: 'node 2' },
|
||||
{ id: 'next', name: 'next', value: 'node 3' },
|
||||
],
|
||||
calculations: [],
|
||||
linkedLists: [
|
||||
{
|
||||
id: 'list',
|
||||
nodes: [
|
||||
{ id: 'n1', value: 1, index: 0, state: 'success' },
|
||||
{ id: 'n2', value: 2, index: 1, state: 'success' },
|
||||
{ id: 'n3', value: 3, index: 2, state: 'comparing' },
|
||||
{ id: 'n4', value: 4, index: 3, state: 'normal' },
|
||||
{ id: 'null', value: 0, index: 4, state: 'normal', isNull: true },
|
||||
],
|
||||
},
|
||||
],
|
||||
linkedListPointers: [
|
||||
{ id: 'prev', name: 'prev', nodeIndex: 0, color: 'prev' },
|
||||
{ id: 'curr', name: 'curr', nodeIndex: 1, color: 'curr' },
|
||||
{ id: 'next', name: 'next', nodeIndex: 2, color: 'next' },
|
||||
],
|
||||
},
|
||||
},
|
||||
{
|
||||
id: 'step-12',
|
||||
phase: 'execution',
|
||||
explanation: 'Move prev = curr, curr = next_node. Advance to process node 3.',
|
||||
codeLine: 8,
|
||||
codeHighlightLines: [8, 9],
|
||||
dataState: {
|
||||
arrays: [],
|
||||
pointers: [],
|
||||
variables: [
|
||||
{ id: 'prev', name: 'prev', value: 'node 2', previousValue: 'node 1' },
|
||||
{ id: 'curr', name: 'curr', value: 'node 3', previousValue: 'node 2' },
|
||||
],
|
||||
calculations: [],
|
||||
linkedLists: [
|
||||
{
|
||||
id: 'list',
|
||||
nodes: [
|
||||
{ id: 'n1', value: 1, index: 0, state: 'success' },
|
||||
{ id: 'n2', value: 2, index: 1, state: 'success' },
|
||||
{ id: 'n3', value: 3, index: 2, state: 'highlighted' },
|
||||
{ id: 'n4', value: 4, index: 3, state: 'normal' },
|
||||
{ id: 'null', value: 0, index: 4, state: 'normal', isNull: true },
|
||||
],
|
||||
},
|
||||
],
|
||||
linkedListPointers: [
|
||||
{ id: 'prev', name: 'prev', nodeIndex: 1, color: 'prev' },
|
||||
{ id: 'curr', name: 'curr', nodeIndex: 2, color: 'curr' },
|
||||
],
|
||||
},
|
||||
},
|
||||
// Iteration 3 (condensed)
|
||||
{
|
||||
id: 'step-13',
|
||||
phase: 'execution',
|
||||
explanation: 'Process node 3: save next (node 4), reverse link (3→2), advance pointers.',
|
||||
codeLine: 6,
|
||||
codeHighlightLines: [6, 7, 8, 9],
|
||||
dataState: {
|
||||
arrays: [],
|
||||
pointers: [],
|
||||
variables: [
|
||||
{ id: 'prev', name: 'prev', value: 'node 3', previousValue: 'node 2' },
|
||||
{ id: 'curr', name: 'curr', value: 'node 4', previousValue: 'node 3' },
|
||||
],
|
||||
calculations: [],
|
||||
linkedLists: [
|
||||
{
|
||||
id: 'list',
|
||||
nodes: [
|
||||
{ id: 'n1', value: 1, index: 0, state: 'success' },
|
||||
{ id: 'n2', value: 2, index: 1, state: 'success' },
|
||||
{ id: 'n3', value: 3, index: 2, state: 'success' },
|
||||
{ id: 'n4', value: 4, index: 3, state: 'highlighted' },
|
||||
{ id: 'null', value: 0, index: 4, state: 'normal', isNull: true },
|
||||
],
|
||||
},
|
||||
],
|
||||
linkedListPointers: [
|
||||
{ id: 'prev', name: 'prev', nodeIndex: 2, color: 'prev' },
|
||||
{ id: 'curr', name: 'curr', nodeIndex: 3, color: 'curr' },
|
||||
],
|
||||
},
|
||||
},
|
||||
// Iteration 4 (last node)
|
||||
{
|
||||
id: 'step-14',
|
||||
phase: 'execution',
|
||||
explanation: 'Process node 4: save next (null), reverse link (4→3), advance pointers.',
|
||||
codeLine: 6,
|
||||
codeHighlightLines: [6, 7, 8, 9],
|
||||
dataState: {
|
||||
arrays: [],
|
||||
pointers: [],
|
||||
variables: [
|
||||
{ id: 'prev', name: 'prev', value: 'node 4', previousValue: 'node 3' },
|
||||
{ id: 'curr', name: 'curr', value: 'None', previousValue: 'node 4' },
|
||||
],
|
||||
calculations: [],
|
||||
linkedLists: [
|
||||
{
|
||||
id: 'list',
|
||||
nodes: [
|
||||
{ id: 'n1', value: 1, index: 0, state: 'success' },
|
||||
{ id: 'n2', value: 2, index: 1, state: 'success' },
|
||||
{ id: 'n3', value: 3, index: 2, state: 'success' },
|
||||
{ id: 'n4', value: 4, index: 3, state: 'success' },
|
||||
{ id: 'null', value: 0, index: 4, state: 'normal', isNull: true },
|
||||
],
|
||||
},
|
||||
],
|
||||
linkedListPointers: [
|
||||
{ id: 'prev', name: 'prev', nodeIndex: 3, color: 'prev' },
|
||||
],
|
||||
},
|
||||
},
|
||||
// Exit and return
|
||||
{
|
||||
id: 'step-15',
|
||||
phase: 'execution',
|
||||
explanation: 'Check: curr is None. Exit loop. Return prev (node 4), the new head!',
|
||||
codeLine: 11,
|
||||
decision: {
|
||||
question: 'Is curr not None?',
|
||||
answer: 'No, curr is None',
|
||||
action: 'Exit loop, return prev',
|
||||
},
|
||||
dataState: {
|
||||
arrays: [],
|
||||
pointers: [],
|
||||
variables: [
|
||||
{ id: 'prev', name: 'prev', value: 'node 4' },
|
||||
{ id: 'curr', name: 'curr', value: 'None' },
|
||||
{ id: 'result', name: 'result', value: 'node 4 (new head)' },
|
||||
],
|
||||
calculations: [],
|
||||
linkedLists: [
|
||||
{
|
||||
id: 'list',
|
||||
label: 'Reversed: 4 → 3 → 2 → 1 → null',
|
||||
nodes: [
|
||||
{ id: 'n4', value: 4, index: 0, state: 'success' },
|
||||
{ id: 'n3', value: 3, index: 1, state: 'success' },
|
||||
{ id: 'n2', value: 2, index: 2, state: 'success' },
|
||||
{ id: 'n1', value: 1, index: 3, state: 'success' },
|
||||
{ id: 'null', value: 0, index: 4, state: 'normal', isNull: true },
|
||||
],
|
||||
},
|
||||
],
|
||||
linkedListPointers: [],
|
||||
},
|
||||
},
|
||||
],
|
||||
};
|
||||
Reference in New Issue
Block a user