Skip to content

feat(data-structure): JS learning collection — 11 structures + tests#13

Open
rickvian wants to merge 2 commits intomainfrom
feature/data-structures
Open

feat(data-structure): JS learning collection — 11 structures + tests#13
rickvian wants to merge 2 commits intomainfrom
feature/data-structures

Conversation

@rickvian
Copy link
Copy Markdown
Owner

@rickvian rickvian commented May 8, 2026

Summary

Builds out data-structure/ into a teaching-focused collection of hand-rolled JS data structures. Each file is meant to make underlying machinery visible — not to replace native Map/Set/Array in production.

11 structures (with matching Vitest test files in data-structure/tests/):

  • Stack — array-backed LIFO
  • Queue — linked-list backed FIFO (avoids Array.shift O(n))
  • LinkedList — singly linked
  • DoublyLinkedList — sentinel-node design, O(1) removeNode(ref) (the LRU cache primitive)
  • HashMap — separate chaining + djb2 hash + load-factor rehash
  • MaxPriorityQueue (already existed; bug-fixed — see below)
  • MinPriorityQueue — mirror of Max with comparator flipped
  • Trie — prefix tree, Map-of-children for Unicode
  • BST — unbalanced; insert/search/delete (3-case)/iterative in-order
  • Graph — adjacency list, undirected + directed, BFS/DFS iterative
  • UnionFind — path compression + union by rank, returns merge status

Plus data-structure/README.md with when-to-use table and complexity cheat sheet.

Why this shape

  • Teaching first. Every file leads with an ASCII diagram, complexity table, and a "why this representation beats alternatives" note (heap-as-array vs node-pointers, adjacency list vs matrix, sentinel-node trick, etc.).
  • Comments explain why not what. Reasoning, tradeoffs, and pitfalls — not syntax narration.
  • #privateFields everywhere. True encapsulation makes invariants enforceable and reads cleaner than _underscore conventions.
  • Iterative DFS / in-order. Avoids JS call-stack overflow on deep inputs.
  • Tests cover edge cases that matter: empty, single-element, drain-and-refill (queue tail-pointer regression), past-load-factor rehash, skewed BST insert, BFS/DFS direction sensitivity, etc.

Bug fix in existing MaxPriorityQueue.js

Constructor accepted { valueOf } as the priority extractor. valueOf is inherited from Object.prototype — when destructuring { valueOf = (x) => x } = {}, the empty-object default still resolves valueOf via the prototype chain, picking up Object.prototype.valueOf (which returns the receiver). Result: priority(i) returned the heap instance itself, all comparisons evaluated to >=, and the heap silently degenerated into FIFO order on enqueue.

Renamed the option to priorityOf in both Max and Min PQ. JSDoc now warns against the trap. Caught by the new tests; would not have surfaced without them.

Test plan

  • npm run test -- data-structure — 73/73 passing across 11 files
  • Manual repro of the valueOf bug confirmed and resolved
  • Stress tests: 500 random inserts drain in correct order for both MinPQ and MaxPQ
  • HashMap survives crossing the 0.75 load factor threshold (200-entry insert)

🤖 Generated with Claude Code

rickvian added 2 commits May 8, 2026 14:18
- Add Queue class with FIFO functionality backed by a linked list.
- Add Stack class with LIFO functionality backed by a JavaScript array.
- Add Trie class for efficient prefix-based word storage and retrieval.
- Add UnionFind class for disjoint set operations with path compression and union by rank.
- Add various data structure tests for validation and correctness.
- Create README.md for documentation on data structures and their use cases.
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.

1 participant