Skip to content

Commit 585d8f6

Browse files
jonatan5524jonatan
and
jonatan
authored
data-structure: stack (#28)
* feat: add data structure stack * test: add test to stack * chore: refactor code review changes Co-authored-by: jonatan <[email protected]>
1 parent 502e11e commit 585d8f6

File tree

2 files changed

+144
-0
lines changed

2 files changed

+144
-0
lines changed

Data-Structures/Stack.ts

+76
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,76 @@
1+
/* Stack data-structure. It's work is based on the LIFO method (last-IN-first-OUT).
2+
* It means that elements added to the stack are placed on the top and only the
3+
* last element (from the top) can be reached. After we get access to the last
4+
* element, it pops from the stack.
5+
* This is a class-based implementation of a Stack.
6+
*/
7+
export class Stack<T> {
8+
private stack: T[] = [];
9+
private limit: number;
10+
11+
/**
12+
* constructor of the stack, can set a limit, if not provided there is no limit to the stack.
13+
* @param {number} [limit=Number.MAX_VALUE] the limit of the stack
14+
*/
15+
constructor(limit: number = Number.MAX_VALUE) {
16+
this.limit = limit;
17+
}
18+
19+
/**
20+
* @function push
21+
* @description - adds a new element to the stack
22+
* @param {T} value - the new value to add
23+
*/
24+
push(value: T) {
25+
if (this.length() + 1 > this.limit) {
26+
throw new Error('Stack Overflow');
27+
}
28+
29+
this.stack.push(value);
30+
}
31+
32+
/**
33+
* @function pop
34+
* @description - remove an element from the top
35+
* @throws will throw an error if the stack is empty
36+
* @return {T} removed element
37+
*/
38+
pop(): T {
39+
if (this.length() !== 0) {
40+
return this.stack.pop() as T;
41+
}
42+
43+
throw new Error('Stack Underflow');
44+
}
45+
46+
/**
47+
* @function length
48+
* @description - number of elements in the stack
49+
* @return {number} the number of elements in the stack
50+
*/
51+
length(): number {
52+
return this.stack.length;
53+
}
54+
55+
/**
56+
* @function isEmpty
57+
* @description - check if the stack is empty
58+
* @return {boolean} returns true if the stack is empty, otherwise false
59+
*/
60+
isEmpty(): boolean {
61+
return this.length() === 0;
62+
}
63+
64+
/**
65+
* @function top
66+
* @description - return the last element in the stack without removing it
67+
* @return {T | null} return the last element or null if the stack is empty
68+
*/
69+
top(): T | null {
70+
if (this.length() !== 0) {
71+
return this.stack[this.length() - 1];
72+
}
73+
74+
return null;
75+
}
76+
}
+68
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
import { Stack } from '../../Stack';
2+
3+
describe('Testing Stack data structure', () => {
4+
it('push should add a new element to the stack', () => {
5+
const stack = new Stack<number>();
6+
stack.push(2);
7+
8+
expect(stack.length()).toBe(1);
9+
});
10+
11+
it('push should throw error on reach limit', () => {
12+
const stack = new Stack<number>(2);
13+
stack.push(2);
14+
stack.push(3);
15+
16+
expect(() => stack.push(4)).toThrow('Stack Overflow');
17+
});
18+
19+
it('isEmpty should return true on empty stack', () => {
20+
const stack = new Stack<number>();
21+
expect(stack.isEmpty()).toBeTruthy();
22+
});
23+
24+
it('isEmpty should return false on not empty stack', () => {
25+
const stack = new Stack<number>();
26+
stack.push(2);
27+
28+
expect(stack.isEmpty()).toBeFalsy();
29+
});
30+
31+
it('top should return the last value', () => {
32+
const stack = new Stack<number>();
33+
stack.push(2);
34+
35+
expect(stack.top()).toBe(2);
36+
});
37+
38+
it('top should return null when the stack is empty', () => {
39+
const stack = new Stack<number>();
40+
41+
expect(stack.top()).toBe(null);
42+
});
43+
44+
it('length should return the number of elements in the stack', () => {
45+
const stack = new Stack<number>();
46+
stack.push(2);
47+
stack.push(2);
48+
stack.push(2);
49+
50+
expect(stack.length()).toBe(3);
51+
});
52+
53+
it('pop should remove the last element and return it', () => {
54+
const stack = new Stack<number>();
55+
stack.push(1);
56+
stack.push(2);
57+
stack.push(3);
58+
59+
expect(stack.pop()).toBe(3);
60+
expect(stack.length()).toBe(2);
61+
});
62+
63+
it('pop should throw an exception if the stack is empty', () => {
64+
const stack = new Stack<number>();
65+
66+
expect(() => stack.pop()).toThrow('Stack Underflow');
67+
});
68+
});

0 commit comments

Comments
 (0)