0
0
DSA Typescriptprogramming

Tree vs Array vs Linked List When Hierarchy Matters in DSA Typescript - Trade-offs & Analysis

Choose your learning style9 modes available
Mental Model
A tree shows clear parent-child links for hierarchy, arrays list items flatly, and linked lists chain items linearly.
Analogy: Think of a family tree (tree) showing generations, a photo album (array) showing pictures side by side, and a treasure map path (linked list) showing one step after another.
Tree:
    1
   / \
  2   3
 / \
4   5

Array:
[1][2][3][4][5]

Linked List:
1 -> 2 -> 3 -> 4 -> 5 -> null
Dry Run Walkthrough
Input: Tree with nodes 1 as root, 2 and 3 as children of 1, 4 and 5 as children of 2; Array with elements [1,2,3,4,5]; Linked List with nodes 1->2->3->4->5
Goal: Show how each structure represents hierarchy and order differently
Step 1: Look at the tree root node 1 with children 2 and 3
Tree:
    1
   / \
  2   3

Array:
[1][2][3][4][5]

Linked List:
1 -> 2 -> 3 -> 4 -> 5 -> null
Why: Tree shows parent 1 connected to children 2 and 3, representing hierarchy
Step 2: Observe children of node 2 in tree: nodes 4 and 5
Tree:
    1
   / \
  2   3
 / \
4   5

Array:
[1][2][3][4][5]

Linked List:
1 -> 2 -> 3 -> 4 -> 5 -> null
Why: Tree shows deeper hierarchy with 4 and 5 as children of 2, unlike flat array or linear list
Step 3: Look at array elements in order
Tree:
    1
   / \
  2   3
 / \
4   5

Array:
[1][2][3][4][5]

Linked List:
1 -> 2 -> 3 -> 4 -> 5 -> null
Why: Array stores elements flatly without parent-child links, just positions
Step 4: Follow linked list nodes from 1 to 5
Tree:
    1
   / \
  2   3
 / \
4   5

Array:
[1][2][3][4][5]

Linked List:
1 -> 2 -> 3 -> 4 -> 5 -> null
Why: Linked list shows linear order but no branching hierarchy
Result:
Tree:
    1
   / \
  2   3
 / \
4   5

Array:
[1][2][3][4][5]

Linked List:
1 -> 2 -> 3 -> 4 -> 5 -> null
Annotated Code
DSA Typescript
class TreeNode {
  value: number;
  children: TreeNode[];
  constructor(value: number) {
    this.value = value;
    this.children = [];
  }
}

class LinkedListNode {
  value: number;
  next: LinkedListNode | null;
  constructor(value: number) {
    this.value = value;
    this.next = null;
  }
}

// Build tree
function buildTree(): TreeNode {
  const root = new TreeNode(1);
  const node2 = new TreeNode(2);
  const node3 = new TreeNode(3);
  const node4 = new TreeNode(4);
  const node5 = new TreeNode(5);
  root.children.push(node2, node3); // root has children 2 and 3
  node2.children.push(node4, node5); // node 2 has children 4 and 5
  return root;
}

// Print tree in simple indented form
function printTree(node: TreeNode, indent = ""): void {
  console.log(indent + node.value);
  for (const child of node.children) {
    printTree(child, indent + "  ");
  }
}

// Build array
function buildArray(): number[] {
  return [1, 2, 3, 4, 5];
}

// Print array
function printArray(arr: number[]): void {
  console.log(arr.map(x => `[${x}]`).join(''));
}

// Build linked list
function buildLinkedList(): LinkedListNode {
  const head = new LinkedListNode(1);
  let current = head;
  for (let val = 2; val <= 5; val++) {
    current.next = new LinkedListNode(val);
    current = current.next; // advance to next node
  }
  return head;
}

// Print linked list
function printLinkedList(head: LinkedListNode | null): void {
  let curr = head;
  let output = '';
  while (curr !== null) {
    output += curr.value + ' -> ';
    curr = curr.next; // move to next node
  }
  output += 'null';
  console.log(output);
}

// Driver
const treeRoot = buildTree();
console.log('Tree:');
printTree(treeRoot);

const arr = buildArray();
console.log('\nArray:');
printArray(arr);

const linkedListHead = buildLinkedList();
console.log('\nLinked List:');
printLinkedList(linkedListHead);
root.children.push(node2, node3); // root has children 2 and 3
link children nodes to root to build hierarchy
node2.children.push(node4, node5); // node 2 has children 4 and 5
add children to node 2 to deepen hierarchy
current.next = new LinkedListNode(val);
link new node to current tail to build linear chain
curr = curr.next; // move to next node
advance pointer to next node to traverse linked list
OutputSuccess
Tree: 1 2 4 5 3 Array: [1][2][3][4][5] Linked List: 1 -> 2 -> 3 -> 4 -> 5 -> null
Complexity Analysis
Time: O(n) because each structure is built or printed by visiting each element once
Space: O(n) because all structures store n elements explicitly
vs Alternative: Tree uses extra space for child pointers but shows hierarchy clearly; array uses contiguous space but no hierarchy; linked list uses pointers but only linear order
Edge Cases
Empty tree, array, or linked list
Print functions handle empty inputs gracefully without errors
DSA Typescript
while (curr !== null) { ... } in printLinkedList prevents null pointer errors
Single node/tree with one element
Structures show just one element with no children or next nodes
DSA Typescript
for (const child of node.children) { ... } in printTree handles zero children
When to Use This Pattern
When a problem needs to represent parent-child relationships or hierarchy, use a tree; for simple ordered collections, use arrays or linked lists.
Common Mistakes
Mistake: Trying to represent hierarchy using only arrays or linked lists without extra info
Fix: Use tree nodes with child pointers to capture hierarchy explicitly
Summary
Shows how trees represent hierarchy, arrays store flat lists, and linked lists chain items linearly.
Use trees when parent-child relationships matter, arrays for indexed access, and linked lists for linear sequences.
The key is that trees have branching pointers to children, arrays have fixed positions, and linked lists have next pointers forming a chain.