Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -44,9 +44,9 @@ This repository contains implementation of some of the fundamental data structur

## Short-cut to CS2040S Material
1. Basic structures
* Linked List
* Stack
* Queue
* [Linked List](src/dataStructures/linkedList)
* [Stack](src/dataStructures/stack)
* [Queue](src/dataStructures/queue)
2. Binary Search
* Peak Finding
3. Sorting
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package src.dataStructures.stackAndQueue.monotonicQueue;
package src.dataStructures.queue;

import java.util.Deque;
import java.util.ArrayDeque;
Expand All @@ -11,7 +11,14 @@
* max()
* pop()
* push()
* @param <T> generic type for objects to be stored or queried
* @param <T> generic type for objects to be stored or queried
*
* index v Increasing queue Decreasing queue
* 1 5 [5] [5]
* 2 3 [3] 3 kick out 5 [5, 3] #3->5
* 3 1 [1] 1 kick out 3 [5, 3, 1] #1->3
* 4 2 [1, 2] #2->1 [5, 3, 2] 2 kick out 1 #2->3
* 5 4 [1, 2, 4] #4->2 [5,4] 4 kick out 2, 3 #4->2
*/
public class MonotonicQueue<T extends Comparable<T>> {
private Deque<Pair<T>> dq = new ArrayDeque<>(); // or LinkedList
Expand Down Expand Up @@ -54,6 +61,9 @@ public T max() {
* Removal will only be done all representation of the object has been accounted for.
*/
public T pop() {
if (dq.isEmpty()) {
return null;
}
Pair<T> node = dq.peek();
if (node.countDeleted > 0) {
node.countDeleted -= 1;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package src.dataStructures.stackAndQueue.queue;
package src.dataStructures.queue;

/**
* Implementation of a queue structure using LinkedList.
Expand Down
68 changes: 68 additions & 0 deletions src/dataStructures/queue/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
# Queue

A queue is a linear data structure that restricts the order in which operations can be performed on its elements.

### Operation Orders

![Queue](https://media.geeksforgeeks.org/wp-content/cdn-uploads/20221213113312/Queue-Data-Structures.png)

*Source: GeeksForGeeks*

Queue follows a FIFO, first in first out order.
This means the earliest element
added to the stack is the one operations are conducted on first.

A [stack](../stack/README.md) is a queue with operations conducted in an opposite manner.

## Analysis

As a queue only interacts with either the first or last element regardless during its operations,
it only needs to keep the pointers of the two element at hand, which is constantly updated as more
elements are removed / added. This allows stack operations to only incur a *O(1)* time complexity.

## Notes

### Stack vs Queues

Stack and queues only differ in terms of operation order, you should aim to use a stack when
you want the most recent elements to be operated on.
Some situations where a stack would work well include build redo / undo systems and backtracking problems.

On the other hand, a queue allows you to operate on elements that enter first. Some situations where
this would be useful include Breadth First Search algorithms and task / resource allocation systems.

### Arrays vs Linked List
It is worth noting that queues can be implemented with either a array or with a [linked list](../linkedList/README.md).
In the context of ordered operations, the lookup is only restricted to the first element.

Hence, there is not much advantage in using a array, which only has a better lookup speed (*O(1)* time complexity)
to implement a queue. Especially when using a linked list to construct your queue
would allow you to grow or shrink the queue as you wish.

### Queue Variants

These are some variants of queue that are commonly used.

#### Double Ended Queue (Deque)

![Deque](https://media.geeksforgeeks.org/wp-content/uploads/anod.png)

*Source: GeeksForGeeks*

Deque is a variant of queue where elements can be removed or added from the head and tail of the queue.
Deque could come in handy when trying to solve sliding window problems.

A deque can be implemented in multiple ways, using doubly linked lists, arrays or two stacks.

#### Monotonic Queue

This is a variant of queue where elements within the queue are either strictly increasing or decreasing.
Monotonic queues are often implemented with a deque.

Within a increasing monotonic queue, any element that is smaller than the current minimum is removed.
Within a decreasing monotonic queue, any element that is larger than the current maximum is removed.

It is worth mentioning that the most elements added to the monotonic queue would always be in a
increasing / decreasing order,
hence, we only need to compare down the monotonic queue from the back when adding new elements.

40 changes: 40 additions & 0 deletions src/dataStructures/stack/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
# Stack
Stack is a linear data structure that restricts
the order in which operations can be performed on its elements.

![Stack data structure](https://cdn.programiz.com/sites/tutorial2program/files/stack.png)

*Source: Programiz*

### Operation Orders

Stack follows a LIFO, last in first out order.
This means the most recent element
added to the stack is the one operations are conducted on first.

A [queue](../queue/README.md) conducts operations in the opposite order.

## Analysis

As a stack only interacts with the most recent element regardless of operation,
it keeps the pointer of the most recent element at hand, which is constantly updated as more
elements are removed / added. This allows stack operations to only incur a *O(1)* time complexity.

## Notes

### Stack vs Queues

Stack and queues only differ in terms of operation order, you should aim to use a stack when
you want the most recent elements to be operated on.
Some situations where a stack would work well include build redo / undo systems and backtracking problems.

On the other hand, a queue allows you to operate on elements that enter first. Some situations where
this would be useful include Breadth First Search algorithms and task / resource allocation systems.

### Arrays vs Linked List
It is worth noting that stacks can be implemented with either a array or with a [linked list](../linkedList/README.md).
In the context of ordered operations, the lookup is only restricted to the first element.

Hence, there is not much advantage in using a array, which only has a better lookup speed (*O(1)* time complexity)
to implement a stack. Especially when using a linked list to construct your stack
would allow you to grow or shrink the stack as you wish.
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package src.dataStructures.stackAndQueue.stack;
package src.dataStructures.stack;

import java.util.List;
import java.util.ArrayList;
Expand Down
49 changes: 49 additions & 0 deletions test/dataStructures/queue/queueTest.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
package test.dataStructures.queue;

import org.junit.Assert;
import org.junit.Test;
import src.dataStructures.queue.Queue;

public class queueTest {
@Test
public void testEmptyQueue() {
Queue<Integer> q = new Queue<>();
Assert.assertEquals(0, q.size());
Assert.assertEquals(true, q.isEmpty());
Assert.assertEquals(null, q.dequeue());
}
@Test
public void testEnqueue() {
Queue<Integer> q = new Queue<>();
q.enqueue(1);
q.enqueue(2);
q.enqueue(3);
Assert.assertEquals(3, q.size());
}

@Test
public void testPeek() {
Queue<Integer> q = new Queue<>();
q.enqueue(1);
Assert.assertEquals("1", q.peek().toString());
q.enqueue(2);
q.enqueue(3);
q.peek();
Assert.assertEquals("1", q.peek().toString());
}

@Test
public void testDequeue() {
Queue<Integer> q = new Queue<>();
q.enqueue(1);
q.enqueue(2);
q.enqueue(3);
Assert.assertEquals("1", q.dequeue().toString());
Assert.assertEquals(2, q.size());
q.dequeue();
Assert.assertEquals(1, q.size());
Assert.assertEquals("3", q.dequeue().toString());
Assert.assertEquals(0, q.size());
}

}
32 changes: 32 additions & 0 deletions test/dataStructures/stack/StackTest.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
package test.dataStructures.stack;

import org.junit.Assert;
import org.junit.Test;
import src.dataStructures.stack.Stack;
public class StackTest {
@Test
public void testEmpty(){
Stack<Integer> stk = new Stack<>();
Assert.assertEquals(null, stk.pop());
Assert.assertEquals(null, stk.peek());
}

@Test
public void testPopAndPeek() {
Stack<Integer> stk = new Stack<>(1, 2, 3);
Assert.assertEquals("3", stk.peek().toString());
Assert.assertEquals("3", stk.pop().toString());
Assert.assertEquals("2", stk.peek().toString());
}

@Test
public void testPush() {
Stack<Integer> stk = new Stack<>();
stk.push(1);
Assert.assertEquals("1", stk.peek().toString());
stk.push(2);
stk.push(3);
Assert.assertEquals("3", stk.peek().toString());
}

}
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
package test.randomTests.changxian.stackAndQueue.monotonicQueue;

import src.dataStructures.stackAndQueue.monotonicQueue.MonotonicQueue;
import src.dataStructures.queue.MonotonicQueue;

import java.util.Arrays;
import java.util.ArrayList;
Expand Down
2 changes: 1 addition & 1 deletion test/randomTests/changxian/stackAndQueue/queue/Test.java
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
package test.randomTests.changxian.stackAndQueue.queue;

import src.dataStructures.stackAndQueue.queue.Queue;
import src.dataStructures.queue.Queue;

/**
* Basic Testing
Expand Down
2 changes: 1 addition & 1 deletion test/randomTests/changxian/stackAndQueue/stack/Test.java
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
package test.randomTests.changxian.stackAndQueue.stack;

import src.dataStructures.stackAndQueue.stack.Stack;
import src.dataStructures.stack.Stack;

/*
* Basic Testing
Expand Down