Data Structures the Fun Way - 4. Stacks and Queues

Data structures that can read data according to the order in which data was stored

πŸ”– 4.1 Stacks

Implementing Stack with Array

  • When adding data, the stack can be expanded, but there may be additional costs when the array size needs to be expanded.

  • JavaScript arrays have dynamic size, so push() operations are performed quickly if the array size is sufficient, but memory reallocation costs occur when the array size needs to be expanded.

  • When pop()ing items from the stack, the internal operation is simpler than push().

  • push() inserts data at the end of the array and may need to expand memory considering the array size, but pop() is a simple operation of removing the last element of the array.

const stack = [];

stack.push(10); // Add (push)
stack.push(20);
console.log(stack); // [10, 20]

stack.pop(); // Remove (pop)
console.log(stack); // [10]

Implementing Stack with Linked List

  • Using linked lists eliminates size limitations and eliminates the need to worry about memory reallocation.

  • When push()ing items to the stack, a new node is added to the front of the linked list.

  • A new node is created, and the new node's next pointer and the stack's head pointer are updated to insert the new node at the front of the list.

  • When pop()ing, the value of the head node is returned, and the head pointer is moved to the next node.

πŸ”– 4.2 Queues

Implementing Queue with Array

  • Queues can be implemented using push() and shift() of arrays.

  • However, shift() moves all elements of the array forward, so it's costly.

  • To solve this disadvantage, using a circular queue can work efficiently without additional operations of moving from the end to the front of the array.

Implementing Queue with Linked List

  • Using linked lists allows dynamic management of queue size.

  • Maintains a pointer pointing to the head of the list and a pointer pointing to the tail.

  • enqueue() adds a new node to the tail, and dequeue() removes a node from the head.

  • Operations are always performed in constant time (O(1)) regardless of queue size.

πŸ”– 4.3 Importance of Order

Depth-First Search (DFS)

  • A method of proceeding along one path while exploring deeper until reaching a dead end

  • When reaching a dead end, it returns to the last visited branch and checks the next route.

  • Uses a stack to maintain a list of possibilities to explore forward, exploring the most recently inserted possibility first.

Breadth-First Search (BFS)

  • Explores in a similar way to depth-first search, but uses a queue to store future possibilities.

  • At each step, exploration searches the possibility that has waited the longest, branching out in multiple different directions at the same depth before exploring deeper levels.

Summary

  • DFS and BFS both operate at the same speed in that they explore one possibility at a time.

Last updated