Basic Data Structures in JavaScript with Examples

This is a practice of data structures I intend to document so i can visit anytime i need to.

Arrays:

  • An array is a data structure that stores a collection of items in a single list.

  • In JavaScript, arrays are implemented as objects with numbered properties, where the numbers are used to indicate the position of the elements in the array.

  • Examples of array operations include adding or removing elements, accessing elements by their index, and iterating over the elements in the array.

// Initialize an array
const arr = [1, 2, 3, 4];

// Add an element to the end of the array
arr.push(5);  // [1, 2, 3, 4, 5]

// Remove and return the last element of the array
const last = arr.pop();  // 5

// Access an element by its index
console.log(arr[2]);  // 3

// Iterate over the elements in the array
for (let i = 0; i < arr.length; i++) {
  console.log(arr[i]);
}

Stacks:

  • A stack is a data structure that operates on a last-in, first-out (LIFO) principle.

  • In JavaScript, you can implement a stack using an array or a linked list.

  • Examples of stack operations include pushing and popping elements, and checking the element at the top of the stack.

class Stack {
  constructor() {
    this.items = [];
  }

  push(item) {
    this.items.push(item);
  }

  pop() {
    return this.items.pop();
  }

  peek() {
    return this.items[this.items.length - 1];
  }
}

const stack = new Stack();
stack.push(1);
stack.push(2);
stack.push(3);

console.log(stack.peek());  // 3
console.log(stack.pop());  // 3
console.log(stack.peek());  // 2

Linked Lists:

  • A linked list is a data structure that consists of a series of nodes, where each node stores a value and a reference to the next node in the list.

  • In JavaScript, you can implement a linked list using objects and pointers.

  • Examples of linked list operations include inserting and deleting nodes, accessing nodes by their position, and iterating over the nodes in the list.

class Node {
  constructor(val) {
    this.val = val;
    this.next = null;
  }
}

class LinkedList {
  constructor() {
    this.head = null;
    this.tail = null;
  }

  addToTail(val) {
    const newNode = new Node(val);
    if (!this.head) {
      this.head = newNode;
    } else {
      this.tail.next = newNode;
    }
    this.tail = newNode;
  }

  removeHead() {
    const oldHead = this.head;
    this.head = this.head.next;
    return oldHead.val;
  }
}

const list = new LinkedList();
list.addToTail(1);
list.addToTail(2);
list.addToTail(3);

console.log(list.removeHead());  // 1
console.log(list.removeHead());  // 2

Queues:

  • A queue is a data structure that operates on a first-in, first-out (FIFO) principle.

  • In JavaScript, you can implement a queue using an array or a linked list.

  • Examples of queue operations include enqueuing and dequeuing elements, and checking the element at the front of the queue.

class Queue {
  constructor() {
    this.items = [];
  }

  enqueue(item) {
    this.items.push(item);
  }

  dequeue() {
    return this.items.shift();
  }

  peek() {
    return this.items[0];
  }
}

const queue = new Queue();
queue.enqueue(1);
queue.enqueue(2);
queue.enqueue(3);

console.log(queue.peek());  // 1
console.log(queue.dequeue());  // 1
console.log(queue.peek());  // 2

Trees:

  • A tree is a data structure that consists of nodes arranged in a hierarchy, with a root node at the top and leaf nodes at the bottom.

  • In JavaScript, you can implement a tree using objects and pointers.

  • Examples of tree operations include inserting and deleting nodes, traversing the tree, and searching for specific nodes.

class TreeNode {
  constructor(val) {
    this.val = val;
    this.left = null;
    this.right = null;
  }
}

class BinarySearchTree {
  constructor() {
    this.root = null;
  }

  insert(val) {
    const newNode = new TreeNode(val);
    if (!this.root) {
      this.root = newNode;
      return;
    }
    let current = this.root;
    while (current) {
      if (val < current.val) {
        if (!current.left) {
          current.left = newNode;
          return;
        }
        current = current.left;
      } else {
        if (!current.right) {
          current.right = newNode;
          return;
        }
        current = current.right;
      }
    }
  }

  search(val) {
    if (!this.root) return false;
    let current = this.root;
    while (current) {
      if (val === current.val) return true;
      if (val < current.val) {
        current = current.left;
      } else {
        current = current.right;
      }
    }
    return false;
  }
}

const tree = new BinarySearchTree();
tree.insert(10);
tree.insert(5);
tree.insert(15);
tree.insert(3);
tree.insert(7);

console.log(tree.search(7));  // true
console.log(tree.search(1));  // false