DEV Community

Cover image for 6 Common Data Structures in Programming
Rizwanul Islam Rudra
Rizwanul Islam Rudra

Posted on

6 Common Data Structures in Programming

Data structures are the building blocks of efficient software in programming. Understanding when and why to use each one can elevate your problem-solving skills. Here, we explore 6 essential data structures, delving into their characteristics, use cases, and implementation in TypeScript. Each section includes diagrams and code examples for clarity.

1. Array

An array is a contiguous block of memory where elements of the same type are stored.

Characteristics:

  • Fast access via index.

  • Fixed-size (in most languages).

  • Can hold duplicate values.

When to Use: Arrays are used to store ordered collections of elements where quick random access is required.

Code Example

const fruits: string[] = ['apple', 'banana', 'cherry'];
console.log(fruits[1]); // Outputs: banana
Enter fullscreen mode Exit fullscreen mode

Visualization

Array Data Structure

2. Linked List

A linked list is a collection of nodes where each node contains data and a reference to the next node.

Characteristics:

  • Dynamic size.
  • Inefficient random access.
  • Efficient insertions/deletions.

When to Use: Use linked lists for applications requiring frequent insertions and deletions, such as undo functionality in editors.

Code Example

class Node<T> {
  value: T;
  next: Node<T> | null = null;
  constructor(value: T) {
    this.value = value;
  }
}

class LinkedList<T> {
  head: Node<T> | null = null;

  add(value: T) {
    const newNode = new Node(value);
    if (!this.head) {
      this.head = newNode;
    } else {
      let current = this.head;
      while (current.next) {
        current = current.next;
      }
      current.next = newNode;
    }
  }
}

const list = new LinkedList<number>();
list.add(10);
list.add(20);
console.log(JSON.stringify(list)); 
// Outputs: {"head":{"value":10,"next":{"value":20,"next":null}}}
Enter fullscreen mode Exit fullscreen mode

Visualization

Linked List

3. Stack

A stack is a LIFO (Last In, First Out) data structure.

Characteristics:

  • Push and pop operations.
  • Useful for backtracking, such as in DFS or expression evaluation.

When to Use: Use stacks for managing function calls, syntax parsing, or undo operations.

Code Example

class Stack<T> {
  private items: T[] = [];
  push(item: T): void {
    this.items.push(item);
  }
  pop(): T | undefined {
    return this.items.pop();
  }
  display(): void {
    console.log(this.items.reverse());
  }
}

const stack = new Stack<number>();
stack.push(1);
stack.push(2);
stack.push(3);
stack.display(); // Outputs: [3, 2, 1]
console.log(stack.pop()); // Returns 3

Enter fullscreen mode Exit fullscreen mode

Visualization

Stack Data Structure

4. Queue

A queue is a FIFO (First In, First Out) data structure.

Characteristics:

  • Enqueue and dequeue operations.
  • Used in scheduling and buffering.

When to Use: Use queues for managing tasks, such as job scheduling or breadth-first search.

Code Example

class Queue<T> {
  private items: T[] = [];
  enqueue(item: T): void {
    this.items.push(item);
  }
  dequeue(): T | undefined {
    return this.items.shift();
  }
  display(): void {
    console.log(this.items);
  }
}

const queue = new Queue<number>();
queue.enqueue(1);
queue.enqueue(2);
queue.enqueue(3);
queue.display(); // Outputs: [1, 2, 3]
console.log(queue.dequeue()); // Returns 1
Enter fullscreen mode Exit fullscreen mode

Visualization

Queue Data Structure

5. Hash Table

A hash table is a key-value pair data structure optimized for quick lookups.

Characteristics:

  • Average O(1) time complexity for lookup and insertion.
  • Handles collisions using chaining or open addressing.

When to Use: Use hash tables for dictionaries, caching, and sets.

Code Example

class HashTable<K, V> {
  private buckets: [K, V][][] = [];

  private hash(key: K): number {
    return JSON.stringify(key).length % 10;
  }

  set(key: K, value: V): void {
    const index = this.hash(key);
    this.buckets[index] = this.buckets[index] || [];
    this.buckets[index].push([key, value]);
  }

  get(key: K): V | undefined {
    const index = this.hash(key);
    const bucket = this.buckets[index] || [];
    for (const [k, v] of bucket) {
      if (k === key) return v;
    }
  }
}

const hashTable = new HashTable<string, number>();
hashTable.set("name", "Alice");
hashTable.set("age", 30);
console.log(hashTable.get("age")); // Outputs: 30
Enter fullscreen mode Exit fullscreen mode

Visualization

Hash Table

6. Binary Tree

A binary tree is a hierarchical structure where each node has up to two children.

Characteristics:

  • Traversals include inorder, preorder, and postorder.
  • Basis for binary search trees (BST).

When to Use: Use binary trees for hierarchical data like file systems.

Code Example

class TreeNode<T> {
  value: T;
  left: TreeNode<T> | null = null;
  right: TreeNode<T> | null = null;

  constructor(value: T) {
    this.value = value;
  }
}

const root = new TreeNode(1);
root.left = new TreeNode(2);
root.right = new TreeNode(3);
console.log(JSON.stringify(root));
// Outputs: {"value":1,"left":{"value":2,"left":null,"right":null},"right":{"value":3,"left":null,"right":null}}
Enter fullscreen mode Exit fullscreen mode

Visualization

Binary Tree

Conclusion

Understanding data structures is crucial for writing efficient and scalable code. Arrays, linked lists, stacks, queues, hash tables, and binary trees each serve specific purposes, from managing order to organizing data hierarchically.

Mastering these basics empowers you to solve diverse challenges, whether in coding interviews or real-world projects. Practice regularly, and you'll quickly see the impact on your problem-solving skills.

References for Further Learning

Books:

Interactive Platforms:

  • LeetCode - Solve coding problems using these structures.
  • GeeksforGeeks - Comprehensive articles on data structures.
  • HackerRank - Learn and practice data structures hands-on.

Courses:

Follow me on X for more!

Top comments (0)