Skip to content

feat: add doubly, circular, and circular doubly linked list types (#676)#682

Open
Sriharshitha156 wants to merge 2 commits into
algoscope-hq:mainfrom
Sriharshitha156:feature/linked-list-types
Open

feat: add doubly, circular, and circular doubly linked list types (#676)#682
Sriharshitha156 wants to merge 2 commits into
algoscope-hq:mainfrom
Sriharshitha156:feature/linked-list-types

Conversation

@Sriharshitha156

@Sriharshitha156 Sriharshitha156 commented Jun 19, 2026

Copy link
Copy Markdown
Contributor

Pull Request Summary

What changed?

Extended the LinkedList component (src/components/dataStructures/LinkedListIV.jsx) to support four linked list types via a tab switcher: Singly, Doubly, Circular, and Circular Doubly. Each type includes insert at beginning, insert at end, delete, animated search, and clear operations with distinct color themes matching the existing design system.

Why is this needed?

Previously AlgoScope only supported Singly Linked List visualization, limiting the learning experience for users exploring different data structure variations.

Closes #676

Type of Change

  • feat - New user-facing feature or algorithm capability

Release Notes

Release note category:

  • Added

Release note entry:

  • Added Doubly, Circular, and Circular Doubly Linked List visualizations with interactive insert, delete, animated search, and clear operations

Testing and Verification

  • npm ci or npm install
  • Manual browser testing at http://localhost:5173
  • No new console errors or warnings

Skipped or additional testing notes:
Skipped npm run format:check, npm run lint, and npm run build as this is a UI-only component change with no routing, dependency, or build configuration updates.

UI Evidence

Before:
image

After:
image

CI/CD and Deployment Impact

  • No deployment impact expected

Deployment notes:
No secrets, environment variables, or migration steps required.

Summary by CodeRabbit

  • New Features
    • Linked list visualizer now supports four types: Singly, Doubly, Circular (singly), and Circular Doubly linked lists
    • Added tab-based interface for easy switching between different list types
    • Smooth animations when transitioning between visualizations
    • Enhanced visualization with type-specific pointer and boundary rendering

@vercel

vercel Bot commented Jun 19, 2026

Copy link
Copy Markdown

@Sriharshitha156 is attempting to deploy a commit to the adityapaul2603-gmailcom's projects Team on Vercel.

A member of the Team first needs to authorize it.

@netlify

netlify Bot commented Jun 19, 2026

Copy link
Copy Markdown

Deploy Preview for astounding-nougat-da0f6a ready!

Name Link
🔨 Latest commit e0e9ac0
🔍 Latest deploy log https://app.netlify.com/projects/astounding-nougat-da0f6a/deploys/6a34a5f7a707640008c1d12f
😎 Deploy Preview https://deploy-preview-682--astounding-nougat-da0f6a.netlify.app
📱 Preview on mobile
Toggle QR Code...

QR Code

Use your smartphone camera to open QR code link.

To edit notification comments on pull requests, go to your Netlify project configuration.

@coderabbitai

coderabbitai Bot commented Jun 19, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

Warning

Review limit reached

@Sriharshitha156, we couldn't start this review because you've reached your PR review rate limit.

More reviews will be available in 54 minutes and 12 seconds. Learn how PR review limits work.

Your organization has used up its prepaid credits, and credit purchases are no longer available. Enable the review add-on in the billing tab to keep reviews running — you're only billed for reviews past your plan's rate limits ($0.25/file).

⌛ How to resolve this issue?

After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based credits.

🚦 How do rate limits work?

CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan refill rate.

For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, the refill rate gradually slows as usage increases. The highest same-day bursts are limited more strictly.

Please see our Fair Usage Limits Policy for further information.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yml

Review profile: CHILL

Plan: Pro Plus

Run ID: 674b9747-ed85-4895-9e70-e44c750c4873

📥 Commits

Reviewing files that changed from the base of the PR and between 62bae01 and e0e9ac0.

📒 Files selected for processing (1)
  • README.md
📝 Walkthrough

Walkthrough

LinkedListIV.jsx is refactored from a single singly-linked-list visualizer into a tabbed component supporting four list types: Singly, Doubly, Circular, and Circular Doubly. Shared presentational subcomponents (Controls, Message, Legend, NodeBox, etc.) are extracted, and AnimatePresence animates tab switching.

Changes

Multi-Type Linked List Visualizer

Layer / File(s) Summary
Shared subcomponents and Controls
src/components/dataStructures/LinkedListIV.jsx
Defines colorMap, NodeBox, Arrow, HeadLabel, EmptyState, Message, and Legend presentational primitives, plus a reusable Controls component wiring the input field, Enter-key shortcut, and all five operation buttons with isSearching/nodesLength-based disabled states.
SinglyLinkedList implementation
src/components/dataStructures/LinkedListIV.jsx
Implements SinglyLinkedList state (nodes, inputVal, message, highlighted, isSearching), insert-at-beginning/end with trim guards, Date.now()-based node IDs, async animated searchNode, deleteNode, and clearList, with framer-motion animated node rendering using shared subcomponents.
DoublyLinkedList implementation
src/components/dataStructures/LinkedListIV.jsx
Adds DoublyLinkedList with mirrored insert/delete/search/clear operations, a prev/next pointer cell layout per node, bidirectional arrow indicators between adjacent nodes, and a doubly-specific Legend.
Circular and CircularDoubly implementations
src/components/dataStructures/LinkedListIV.jsx
Adds CircularLinkedList with loop arrow rendering and a ↩ HEAD tail boundary indicator, then CircularDoublyLinkedList with prev/data/next cells, TAIL ↩ / ↩ HEAD boundary indicators, and their respective Legends.
Root tab switcher export
src/components/dataStructures/LinkedListIV.jsx
Replaces the old single-list export with a TABS array, activeTab state, a rendered tab bar, and AnimatePresence-animated mounting of the active list component.

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

Possibly related issues

Possibly related PRs

  • algoscope-hq/AlgoScope#650: Directly related — that PR introduced the original LinkedListIV.jsx singly-linked-list implementation that this PR expands into a tabbed multi-type visualizer.

Suggested labels

gssoc:approved, type:feature, level:advanced

Suggested reviewers

  • Bimbok

Hey, great feature addition! 👋 Here are a few things worth thinking through before merging:

🧠 Algorithm edge case: Date.now() as node ID

Using Date.now() for IDs is fine in most cases, but if a user inserts nodes in rapid succession (e.g., holding Enter), two nodes could collide on the same millisecond timestamp — both getting the same key, which breaks React's reconciliation and could cause weird rendering bugs. A safer pattern is a module-level incrementing counter:

let _nodeId = 0;
const nextId = () => ++_nodeId;

🔁 Async search and stale closures

The searchNode function is async and reads nodes from state inside the loop. If deleteNode or clearList fires while a search animation is running, the nodes reference inside the async closure is stale. Consider using a useRef to track the live nodes, or cancel the search when the list changes.

⚡ Performance: four independent list states

Each of the four list components mounts with fresh state when its tab becomes active (because AnimatePresence unmounts the previous one). That's intentional, but worth documenting — users will lose their list contents when switching tabs. If persistence across tab switches is desired later, lifting state up would be needed.

🧩 Code duplication across the four list types

The insert/delete/search/clear logic is nearly identical in all four components — the only meaningful difference is the pointer wiring in the render output. Extracting a useLinkedList(type) custom hook for shared logic would make each list component much easier to maintain and test independently.

🔍 deleteNode matches the first occurrence only

That's a reasonable and intentional choice, but it's not communicated to the user. A small note in the message state (e.g., "First occurrence of X deleted") would help learners understand the traversal semantics. Same applies to the search — clarifying "first match" vs "all matches" is a great learning moment!

🚥 Pre-merge checks | ✅ 6 | ❌ 1

❌ Failed checks (1 inconclusive)

Check name Status Explanation Resolution
Algorithm Complexity ❓ Inconclusive No time/space complexity documentation exists in the LinkedListIV.jsx code, PR description, or linked issue to verify against. Cannot assess if implementation matches documented complexity without... The check requires documented algorithm complexity claims to validate. Either add complexity documentation to the component (e.g., JSDoc comments noting O(n) insert/delete/search) or clarify if this check applies to this visualization-fo...
✅ Passed checks (6 passed)
Check name Status Explanation
Title check ✅ Passed The title accurately summarizes the main feature: adding three new linked list types (doubly, circular, circular doubly) to the existing singly linked list visualization.
Description check ✅ Passed The PR description is well-structured, following the template with all critical sections completed: what changed, why it's needed, correct type selection, release notes, testing verification, UI evidence, and deployment impact.
Linked Issues check ✅ Passed The PR fully addresses issue #676 requirements: it extends LinkedList to support Doubly, Circular, and Circular Doubly linked lists with visualization, core operations (insert, delete, traverse/search), and interactive controls.
Out of Scope Changes check ✅ Passed All changes are tightly scoped to the LinkedListIV component. The refactor consolidates related functionality into a single tabbed interface without modifying unrelated files or introducing out-of-scope features.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Conventional Commits ✅ Passed Commit message "feat: add doubly, circular, and circular doubly linked list types (#676)" follows conventional commits standard with proper type prefix, clear description, and issue reference.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
src/components/dataStructures/LinkedListIV.jsx (1)

40-61: ⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Stale closure in searchNode can cause visual glitches if list is modified mid-search.

The searchNode function captures nodes from the closure when called. If the user clicks "Clear" (or modifies the list) while a search is in progress, the function continues iterating over the stale nodes array. This can cause:

  • Accessing nodes that no longer exist in state
  • Highlighting mismatches between the captured array and displayed nodes

The same pattern exists in all four list implementations. Two quick fixes:

  1. Disable Clear during search (minimal fix):
- <button onClick={onClear}
+ <button onClick={onClear} disabled={isSearching}
  1. Or abort search on clear by adding an AbortController or ref-based cancellation flag.

Option 1 is simpler and maintains UX consistency (other buttons are already disabled during search).

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/components/dataStructures/LinkedListIV.jsx` around lines 40 - 61, The
searchNode function captures the nodes array in a closure, so if the list is
cleared while a search is in progress, the function continues iterating over
stale data and highlighting nodes that no longer exist. Disable the Clear button
(which calls the clearList function) when isSearching is true, similar to how
other buttons are already disabled during search. This prevents users from
modifying the list mid-search and eliminates the stale closure problem without
requiring more complex cancellation logic.
🧹 Nitpick comments (1)
src/components/dataStructures/LinkedListIV.jsx (1)

7-112: ⚖️ Poor tradeoff

Consider extracting shared list logic into a custom hook.

All four list implementations have nearly identical state and operations (insert, delete, search, clear). This ~200 lines of duplicated logic could be consolidated:

const useLinkedListState = () => {
  const [nodes, setNodes] = useState([])
  const [inputVal, setInputVal] = useState('')
  const [message, setMessage] = useState('')
  const [highlighted, setHighlighted] = useState(null)
  const [isSearching, setIsSearching] = useState(false)

  const insertAtBeginning = () => { /* ... */ }
  const insertAtEnd = () => { /* ... */ }
  const deleteNode = () => { /* ... */ }
  const searchNode = async () => { /* ... */ }
  const clearList = () => { /* ... */ }

  return { nodes, inputVal, setInputVal, message, highlighted, isSearching,
           insertAtBeginning, insertAtEnd, deleteNode, searchNode, clearList }
}

Then each list component focuses only on its unique rendering logic. This makes fixing bugs (like the stale closure issue) a one-place change. Not blocking, but worth considering for maintainability.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/components/dataStructures/LinkedListIV.jsx` around lines 7 - 112, Extract
the duplicated state management and list operations logic from the
SinglyLinkedList component into a custom hook called useLinkedListState. This
hook should contain all the useState declarations (nodes, inputVal, message,
highlighted, isSearching) and all the operation functions (insertAtBeginning,
insertAtEnd, deleteNode, searchNode, clearList), then return an object with all
these values and functions. Replace the inline state and function definitions in
SinglyLinkedList with a single call to this new hook, destructuring all returned
values. Then apply the same refactoring to the other three list implementations
to eliminate the ~200 lines of duplicated code across all four components and
make future bug fixes a one-place change.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@src/components/dataStructures/LinkedListIV.jsx`:
- Around line 311-313: The apostrophe in "tail's" within the text content of the
p element in LinkedListIV.jsx is causing an ESLint error and needs to be
escaped. Replace the unescaped apostrophe in "tail's" with the HTML entity
&apos; so it reads "tail&apos;s" to properly escape the character in JSX.
- Around line 442-444: In the paragraph element describing the circular doubly
linked list structure, the apostrophe in "head's" within the text "head (and
head's prev to tail)" is unescaped and causing an ESLint error. Escape the
apostrophe by replacing "head's" with "head&apos;s" to properly handle the
special character in the JSX text content.

---

Outside diff comments:
In `@src/components/dataStructures/LinkedListIV.jsx`:
- Around line 40-61: The searchNode function captures the nodes array in a
closure, so if the list is cleared while a search is in progress, the function
continues iterating over stale data and highlighting nodes that no longer exist.
Disable the Clear button (which calls the clearList function) when isSearching
is true, similar to how other buttons are already disabled during search. This
prevents users from modifying the list mid-search and eliminates the stale
closure problem without requiring more complex cancellation logic.

---

Nitpick comments:
In `@src/components/dataStructures/LinkedListIV.jsx`:
- Around line 7-112: Extract the duplicated state management and list operations
logic from the SinglyLinkedList component into a custom hook called
useLinkedListState. This hook should contain all the useState declarations
(nodes, inputVal, message, highlighted, isSearching) and all the operation
functions (insertAtBeginning, insertAtEnd, deleteNode, searchNode, clearList),
then return an object with all these values and functions. Replace the inline
state and function definitions in SinglyLinkedList with a single call to this
new hook, destructuring all returned values. Then apply the same refactoring to
the other three list implementations to eliminate the ~200 lines of duplicated
code across all four components and make future bug fixes a one-place change.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yml

Review profile: CHILL

Plan: Pro Plus

Run ID: 792c3e65-cd85-4dce-962e-17eff0ec3f68

📥 Commits

Reviewing files that changed from the base of the PR and between 0974299 and 62bae01.

📒 Files selected for processing (1)
  • src/components/dataStructures/LinkedListIV.jsx

Comment on lines +311 to +313
<p className="text-slate-400 text-sm">
The <span className="text-green-400">tail's next pointer</span> points back to the <span className="text-green-400">head</span> — forming a circle with no null end.
</p>

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Escape the apostrophe to fix ESLint error.

The apostrophe in "tail's" needs escaping in JSX.

Fix
-        The <span className="text-green-400">tail's next pointer</span> points back to the <span className="text-green-400">head</span> — forming a circle with no null end.
+        The <span className="text-green-400">tail&apos;s next pointer</span> points back to the <span className="text-green-400">head</span> — forming a circle with no null end.
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
<p className="text-slate-400 text-sm">
The <span className="text-green-400">tail's next pointer</span> points back to the <span className="text-green-400">head</span> — forming a circle with no null end.
</p>
<p className="text-slate-400 text-sm">
The <span className="text-green-400">tail&apos;s next pointer</span> points back to the <span className="text-green-400">head</span> forming a circle with no null end.
</p>
🧰 Tools
🪛 ESLint

[error] 312-312: ' can be escaped with &apos;, &lsquo;, &#39;, &rsquo;.

(react/no-unescaped-entities)

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/components/dataStructures/LinkedListIV.jsx` around lines 311 - 313, The
apostrophe in "tail's" within the text content of the p element in
LinkedListIV.jsx is causing an ESLint error and needs to be escaped. Replace the
unescaped apostrophe in "tail's" with the HTML entity &apos; so it reads
"tail&apos;s" to properly escape the character in JSX.

Source: Linters/SAST tools

Comment on lines +442 to +444
<p className="text-slate-400 text-sm">
Combines doubly and circular — <span className="text-orange-400">prev & next</span> pointers, and tail connects back to head (and head's prev to tail).
</p>

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Escape the apostrophe to fix ESLint error.

Same issue as CircularLinkedList - the apostrophe in "head's" needs escaping.

Fix
-        Combines doubly and circular — <span className="text-orange-400">prev & next</span> pointers, and tail connects back to head (and head's prev to tail).
+        Combines doubly and circular — <span className="text-orange-400">prev &amp; next</span> pointers, and tail connects back to head (and head&apos;s prev to tail).
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
<p className="text-slate-400 text-sm">
Combines doubly and circular <span className="text-orange-400">prev & next</span> pointers, and tail connects back to head (and head's prev to tail).
</p>
<p className="text-slate-400 text-sm">
Combines doubly and circular <span className="text-orange-400">prev &amp; next</span> pointers, and tail connects back to head (and head&apos;s prev to tail).
</p>
🧰 Tools
🪛 ESLint

[error] 443-443: ' can be escaped with &apos;, &lsquo;, &#39;, &rsquo;.

(react/no-unescaped-entities)

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/components/dataStructures/LinkedListIV.jsx` around lines 442 - 444, In
the paragraph element describing the circular doubly linked list structure, the
apostrophe in "head's" within the text "head (and head's prev to tail)" is
unescaped and causing an ESLint error. Escape the apostrophe by replacing
"head's" with "head&apos;s" to properly handle the special character in the JSX
text content.

Source: Linters/SAST tools

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Feature]: add types of linkedlist

1 participant