Skip to content

Commit 124890c

Browse files
co-bbyappgurueu
andauthored
feat: add Linked Queue (#88)
* feat: add Array Queue to Directory.md * feat: add linkedlist Queue * feat: add test for linkedlist queue * feat: update Directory.md * fixed typos and formatting * BREAKING CHANGE: change front to peek * fix: added the queue interface * fix: duplication of queue interface and minor bug * fix: queue test problem * fix: change filename to match naming convention * fix: leading newline and time complexity * feat: add jsDoc comments * Rename Queue.test.ts to queue.test.ts * Update queue.test.ts * Update array_queue.test.ts * Update and rename linkedlist_queue.test.ts to linked_queue.test.ts * Update and rename linkedlist_queue.ts to linked_queue.ts * Update linked_queue.test.ts * Update linked_queue.test.ts * Rename queue.test.ts to queue.ts * Update array_queue.test.ts * Update linked_queue.test.ts Co-authored-by: Lars Müller <[email protected]>
1 parent a97a3b2 commit 124890c

File tree

7 files changed

+165
-60
lines changed

7 files changed

+165
-60
lines changed

DIRECTORY.md

+1
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
## Data Structures
66
* [Stack](https://github.com/TheAlgorithms/TypeScript/blob/HEAD/data_structures/stack.ts)
77
* [Array Queue](https://github.com/TheAlgorithms/TypeScript/blob/HEAD/data_structures/array_queue.ts)
8+
* [Linkedlist Queue](https://github.com/TheAlgorithms/TypeScript/blob/HEAD/data_structures/linkedlist_queue.ts)
89

910
## Dynamic Programming
1011
* [Knapsack](https://github.com/TheAlgorithms/TypeScript/blob/HEAD/dynamic_programming/knapsack.ts)

data_structures/array_queue.ts

+3-2
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,8 @@
44
* It means that the first element that was added to the queue will be the first one to be removed.
55
* The time complexity of the operations is O(n).
66
*/
7-
export class ArrayQueue<T> {
7+
import { Queue } from './queue'
8+
export class ArrayQueue<T> implements Queue<T>{
89
private queue: T[] = [];
910

1011
/**
@@ -53,7 +54,7 @@ export class ArrayQueue<T> {
5354
*
5455
* @returns The item at the front of the queue or null if the queue is empty.
5556
*/
56-
front(): T | null {
57+
peek(): T | null {
5758
if (this.isEmpty()) {
5859
return null;
5960
}

data_structures/linked_queue.ts

+95
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,95 @@
1+
import { Queue } from "./queue";
2+
3+
type Node<T> = {
4+
value: T,
5+
next?: Node<T>,
6+
}
7+
8+
/**
9+
* This is a LinkedList-like implementation of a Queue,
10+
* allowing the operations to be implemented in constant time.
11+
* A Queue is a data structure that follows the FIFO (First-In First-Out) principle:
12+
* The first element that was added to the queue will be the first one to be removed.
13+
*/
14+
export class LinkedQueue<T> implements Queue<T> {
15+
16+
public size: number;
17+
public head?: Node<T>;
18+
private tail?: Node<T>;
19+
20+
constructor() {
21+
this.head = this.tail = undefined;
22+
this.size = 0;
23+
}
24+
25+
/**
26+
* Adds an item to the queue.
27+
*
28+
* @param item The item being added to the queue.
29+
*/
30+
enqueue(item: T): void {
31+
const node = { value: item } as Node<T>; // Creates a new node
32+
this.size++ // Increase the length of the Queue
33+
34+
35+
if (!this.tail) {
36+
this.tail = this.head = node;
37+
return;
38+
}
39+
this.tail.next = node; // Updates the next tail to the node created
40+
this.tail = node; // The tail of the Queue then becomes the node created!!
41+
42+
}
43+
44+
45+
/**
46+
* Removes an item from the queue and returns it.
47+
*
48+
* @throws Queue Underflow if the queue is empty.
49+
* @returns The item that was removed from the queue.
50+
*/
51+
dequeue(): T | undefined {
52+
53+
if (!this.head) {
54+
throw new Error("Queue Underflow");
55+
}
56+
57+
this.size--;
58+
let head = this.head; // We store the head in order not to lose track of it
59+
this.head = this.head.next; // Update the the head to the next node
60+
return head.value; // Return the value of the head
61+
}
62+
63+
64+
/**
65+
* Returns the item at the front of the queue.
66+
*
67+
* @returns The item at the front of the queue or null if the queue is empty.
68+
*/
69+
peek(): T | undefined | null {
70+
71+
if (this.isEmpty()) {
72+
return null;
73+
}
74+
return this.head?.value;
75+
}
76+
77+
/**
78+
* Checks if the queue is empty.
79+
*
80+
* @returns {boolean} Whether the queue is empty or not.
81+
*/
82+
isEmpty(): boolean {
83+
return this.size === 0
84+
}
85+
86+
/**
87+
* Returns the number of items in the queue.
88+
*
89+
* @returns {number} The number of items in the queue.
90+
*/
91+
length(): number {
92+
return this.size;
93+
}
94+
}
95+

data_structures/queue.ts

+7
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
export interface Queue<T> {
2+
enqueue(item: T): void
3+
dequeue(): T | undefined
4+
peek(): T | undefined | null
5+
isEmpty(): boolean
6+
length(): number
7+
}
+2-58
Original file line numberDiff line numberDiff line change
@@ -1,60 +1,4 @@
11
import { ArrayQueue } from "../array_queue";
2+
import { testQueue } from './queue'
23

3-
describe("Testing Queue data structure", () => {
4-
it("enqueue should add a new element to the queue", () => {
5-
const queue = new ArrayQueue<number>();
6-
queue.enqueue(1);
7-
8-
expect(queue.length()).toBe(1);
9-
});
10-
11-
it("isEmpty should return true on empty queue", () => {
12-
const queue = new ArrayQueue<number>();
13-
expect(queue.isEmpty()).toBeTruthy();
14-
});
15-
16-
it("isEmpty should return false on not empty queue", () => {
17-
const queue = new ArrayQueue<number>();
18-
queue.enqueue(1);
19-
20-
expect(queue.isEmpty()).toBeFalsy();
21-
});
22-
23-
it("front should return the first value", () => {
24-
const queue = new ArrayQueue<number>();
25-
queue.enqueue(1);
26-
27-
expect(queue.front()).toBe(1);
28-
});
29-
30-
it("front should return null when the queue is empty", () => {
31-
const queue = new ArrayQueue<number>();
32-
33-
expect(queue.front()).toBe(null);
34-
});
35-
36-
it("length should return the number of elements in the queue", () => {
37-
const queue = new ArrayQueue<number>();
38-
queue.enqueue(1);
39-
queue.enqueue(1);
40-
queue.enqueue(1);
41-
42-
expect(queue.length()).toBe(3);
43-
});
44-
45-
it("dequeue should remove the first element", () => {
46-
const queue = new ArrayQueue<number>();
47-
queue.enqueue(1);
48-
queue.enqueue(2);
49-
queue.enqueue(3);
50-
queue.dequeue();
51-
52-
expect(queue.length()).toBe(2);
53-
});
54-
55-
it("dequeue should throw error on empty queue", () => {
56-
const queue = new ArrayQueue<number>();
57-
58-
expect(() => queue.dequeue()).toThrow("Queue Underflow");
59-
});
60-
});
4+
describe("Array Queue", () => testQueue(ArrayQueue));
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
import { testQueue } from './queue'
2+
import { LinkedQueue } from '../linked_queue';
3+
4+
describe("Linked Queue", () => testQueue(LinkedQueue));

data_structures/test/queue.ts

+53
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
import { Queue } from '../queue';
2+
type QueueConstructor = new <T>() => Queue<T>
3+
export function testQueue(Queue: QueueConstructor) {
4+
it("enqueue should add a new element to the queue", () => {
5+
const queue = new Queue<number>();
6+
queue.enqueue(1);
7+
expect(queue.length()).toBe(1);
8+
});
9+
10+
it("isEmpty should return true on empty queue", () => {
11+
const queue = new Queue<number>();
12+
expect(queue.isEmpty()).toBeTruthy();
13+
});
14+
15+
it("isEmpty should return false on not empty queue", () => {
16+
const queue = new Queue<number>();
17+
queue.enqueue(1);
18+
expect(queue.isEmpty()).toBeFalsy();
19+
});
20+
21+
it("front should return the first value", () => {
22+
const queue = new Queue<number>();
23+
queue.enqueue(1);
24+
expect(queue.peek()).toBe(1);
25+
});
26+
27+
it("front should return null when the queue is empty", () => {
28+
const queue = new Queue<number>();
29+
expect(queue.peek()).toBe(null);
30+
});
31+
32+
it("length should return the number of elements in the queue", () => {
33+
const queue = new Queue<number>();
34+
queue.enqueue(1);
35+
queue.enqueue(1);
36+
queue.enqueue(1);
37+
expect(queue.length()).toBe(3);
38+
});
39+
40+
it("dequeue should remove the first element", () => {
41+
const queue = new Queue<number>();
42+
queue.enqueue(1);
43+
queue.enqueue(2);
44+
queue.enqueue(3);
45+
queue.dequeue();
46+
expect(queue.length()).toBe(2);
47+
});
48+
49+
it("dequeue should throw error on empty queue", () => {
50+
const queue = new Queue<number>();
51+
expect(() => queue.dequeue()).toThrow("Queue Underflow");
52+
});
53+
}

0 commit comments

Comments
 (0)