Skip to content

Commit 4341a6f

Browse files
committed
Implement Stack with array, move unit-tests, create array helper
1 parent f9f89ca commit 4341a6f

30 files changed

+153
-117
lines changed

README.md

+9-7
Original file line numberDiff line numberDiff line change
@@ -10,9 +10,9 @@ Most code in TypeScript is done mostly using TDD. Python is done mostly with Jup
1010

1111
Examples:
1212

13-
* [Algorithms](./src/tests/unit-tests/algos)
13+
* [Algorithms](src/tests/algos)
1414
* Data Structures
15-
* [JS Array](./src/tests/unit-tests/data-structures/arrays.test.ts) [(big-o)](./src/tests/unit-tests/data-structures/array.big-o.test.ts)
15+
* [JS Array](src/tests/data-structures/arrays.test.ts) [(big-o)](src/tests/data-structures/array.big-o.test.ts)
1616
* Sort
1717
* Without a sort function it will convert elements into strings, 80 comes before 9
1818
* The sorting algorithm is stable
@@ -24,14 +24,16 @@ Examples:
2424
* === 0 keep original order of a and b
2525
* `const compare = (a, b) => a > b ? -1 : 0;`
2626
* Will have different results in V8 and SpiderMonkey
27-
* [JS Map](./src/tests/unit-tests/data-structures/map.test.ts)
28-
* [JS Set](./src/tests/unit-tests/data-structures/set.test.ts)
29-
* [Singly Linked List](./src/tests/unit-tests/data-structures/singly-linked-list.test.ts)
27+
* [JS Map](src/tests/data-structures/map.test.ts)
28+
* [JS Set](src/tests/data-structures/set.test.ts)
29+
* [Stack using Array](src/tests/data-structures/stack.test.ts)
30+
* [Stack using Linked List](src/tests/data-structures/stack-with-ll.test.ts)
31+
* [Singly Linked List](src/tests/data-structures/singly-linked-list.test.ts)
3032
* Benefits of a sorted list are lost on a sorted SLL
31-
* [Double Linked List](./src/tests/unit-tests/data-structures/double-linked-list.test.ts)
33+
* [Double Linked List](src/tests/data-structures/double-linked-list.test.ts)
3234
* Each node can be anywhere in memory, no need to resize an array
3335
* We don't need to shift position of elements when inserting or deleting like in an array
34-
* [Queue using Double Linked List](./src/tests/unit-tests/data-structures/queue-with-dll.test.ts)
36+
* [Queue using Double Linked List](src/tests/data-structures/queue-with-dll.test.ts)
3537
* Using a DLL allows us to do operations O(1) for enqueue and dequeue
3638
* Faster than using a JS Array or an SLL
3739
* Design Patterns

src/data-structures/sized-stack.ts

-19
This file was deleted.

src/data-structures/stack-with-ll.ts

Whitespace-only changes.

src/data-structures/stack.ts

+39-10
Original file line numberDiff line numberDiff line change
@@ -1,31 +1,60 @@
1+
import { createArrayOfSize } from '../helpers/array';
2+
13
export interface IStack<TValue> {
24
length: number;
35

6+
isFull(): boolean;
7+
isEmpty(): boolean;
48
insert(value: TValue): void;
59
delete(): TValue | undefined;
610
read(): TValue | undefined;
711
}
812

913
export class Stack<TValue> implements IStack<TValue> {
10-
protected _array: TValue[];
11-
12-
constructor() {
13-
this._array = [];
14-
}
14+
protected _array: Array<TValue | undefined>;
15+
protected _maxSize: number;
16+
protected _topPointer: number;
1517

16-
insert(value: TValue): void {
17-
this._array.push(value);
18+
constructor(maxSize: number) {
19+
this._topPointer = -1;
20+
this._maxSize = maxSize;
21+
this._array = createArrayOfSize<TValue | undefined>(maxSize, undefined);
1822
}
1923

2024
delete(): TValue | undefined {
21-
return this._array.pop();
25+
if (this.isEmpty()) {
26+
throw new Error('Stack is empty');
27+
}
28+
const value = this._array[this._topPointer];
29+
this._array[this._topPointer] = undefined;
30+
this._topPointer--;
31+
return value;
2232
}
2333

2434
read(): TValue | undefined {
25-
return this._array[this._array.length - 1];
35+
if (this.isEmpty()) {
36+
return undefined;
37+
}
38+
return this._array[this._topPointer];
2639
}
2740

2841
get length(): number {
29-
return this._array.length;
42+
return this._topPointer + 1;
43+
}
44+
45+
insert(value: TValue): void {
46+
if (this.isFull()) {
47+
throw new Error('Stack is full');
48+
}
49+
this._topPointer++;
50+
this._array[this._topPointer] = value;
51+
}
52+
53+
isEmpty(): boolean {
54+
return this._topPointer === -1;
55+
}
56+
57+
isFull(): boolean {
58+
return this._topPointer + 1 === this._maxSize;
3059
}
3160
}

src/helpers/array.ts

+8
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
export const createArrayOfSize = <T>(size: number, defaultValue: T): T[] => {
2+
let i = 0;
3+
const array: T[] = Array(size);
4+
while (i < size) {
5+
array[i++] = defaultValue;
6+
}
7+
return array;
8+
};

src/tests/unit-tests/algos/binarySearch.test.ts src/tests/algos/binarySearch.test.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { binarySearch } from '../../../algos/binarySearch';
1+
import { binarySearch } from '../../algos/binarySearch';
22

33
describe('binarySearch', () => {
44
it('finds the value', () => {

src/tests/unit-tests/algos/fibonacci.test.ts src/tests/algos/fibonacci.test.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { FIBONACCI_CACHE, fibonacciIterative, fibonacciRecursive, fibonacciRecursiveMemoized } from '../../../algos/fibonacci';
1+
import { FIBONACCI_CACHE, fibonacciIterative, fibonacciRecursive, fibonacciRecursiveMemoized } from '../../algos/fibonacci';
22

33
export const EXPECTED_FIBONACCI_SEQ = [0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144];
44

src/tests/unit-tests/algos/insertSorted.test.ts src/tests/algos/insertSorted.test.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { insertSorted } from '../../../algos/insertSorted';
1+
import { insertSorted } from '../../algos/insertSorted';
22

33
describe('insertSorted', () => {
44
it('should insert a number at the right spot on a sorted array', () => {

src/tests/unit-tests/algos/largest-value.test.ts src/tests/algos/largest-value.test.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { largestValueCompare, largestValueLoop, largestValueBuiltin } from '../../../algos/largest-Value';
1+
import { largestValueCompare, largestValueLoop, largestValueBuiltin } from '../../algos/largest-Value';
22

33
const ONE_VALUE = [1];
44
const ZERO_VALUE = [0];

src/tests/unit-tests/algos/maxIndex.test.ts src/tests/algos/maxIndex.test.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { maxIndex } from '../../../algos/maxIndex';
1+
import { maxIndex } from '../../algos/maxIndex';
22

33
describe('max', () => {
44
it('should return -1 if empty', () => {

src/tests/unit-tests/algos/reverse-double-linked-list.test.ts src/tests/algos/reverse-double-linked-list.test.ts

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
1-
import { DoubleLinkedList } from '../../../data-structures/double-linked-list';
2-
import { reverseDoubleLinkedList } from '../../../algos/reverse-double-linked-list';
1+
import { DoubleLinkedList } from '../../data-structures/double-linked-list';
2+
import { reverseDoubleLinkedList } from '../../algos/reverse-double-linked-list';
33

44
describe('reverse double linked list', () => {
55
it('reverses a double linked list iteratively', () => {

src/tests/unit-tests/algos/reverse-linked-list.test.ts src/tests/algos/reverse-linked-list.test.ts

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
1-
import { SinglyLinkedList } from '../../../data-structures/singly-linked-list';
2-
import { reverseLinkedList, reverseLinkedListRecursive } from '../../../algos/reverse-linked-list';
1+
import { SinglyLinkedList } from '../../data-structures/singly-linked-list';
2+
import { reverseLinkedList, reverseLinkedListRecursive } from '../../algos/reverse-linked-list';
33

44
describe('reverse linked list', () => {
55
it('reverses a linked list iteratively', () => {

src/tests/unit-tests/algos/seqSearch.test.ts src/tests/algos/seqSearch.test.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { seqSearch } from '../../../algos/seqSearch';
1+
import { seqSearch } from '../../algos/seqSearch';
22

33
describe('seqSearch', () => {
44
it('returns -1 if target is not found', () => {

src/tests/unit-tests/algos/sparseMatrix.test.ts src/tests/algos/sparseMatrix.test.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { CSR, sparseMatrixFromCSR, sparseMatrixToCSR } from '../../../algos/sparseMatrix';
1+
import { CSR, sparseMatrixFromCSR, sparseMatrixToCSR } from '../../algos/sparseMatrix';
22

33
interface Sample {
44
to: CSR;

src/tests/unit-tests/algos/twoNumberSum.test.ts src/tests/algos/twoNumberSum.test.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { twoNumberSumLoops, twoNumberSumPointers, twoNumberSumHash } from '../../../algos/twoNumberSum';
1+
import { twoNumberSumLoops, twoNumberSumPointers, twoNumberSumHash } from '../../algos/twoNumberSum';
22

33
describe('twoNumberSum', () => {
44
it('returns the correct values', () => {

src/tests/unit-tests/data-structures/array.big-o.test.ts src/tests/data-structures/array.big-o.test.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { binarySearch } from '../../../algos/binarySearch';
1+
import { binarySearch } from '../../algos/binarySearch';
22

33
describe('array Big-O time', () => {
44
it('returns value at O(1)', () => {

src/tests/unit-tests/data-structures/deque.test.ts src/tests/data-structures/deque.test.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { Deque } from '../../../data-structures/deque';
1+
import { Deque } from '../../data-structures/deque';
22

33
describe('Deque', () => {
44
it('should create an instance', () => {

src/tests/unit-tests/data-structures/double-linked-list.test.ts src/tests/data-structures/double-linked-list.test.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { DoubleLinkedList } from '../../../data-structures/double-linked-list';
1+
import { DoubleLinkedList } from '../../data-structures/double-linked-list';
22

33
describe('DoubleLinkedList', () => {
44
it('should create an instance', () => {

src/tests/unit-tests/data-structures/queue-with-dll.test.ts src/tests/data-structures/queue-with-dll.test.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { QueueWithDoubleLinkedList } from '../../../data-structures/queue-with-dll';
1+
import { QueueWithDoubleLinkedList } from '../../data-structures/queue-with-dll';
22

33
type TaskType = 'wake-up' | 'breakfast' | 'work' | 'lunch' | 'dinner' | 'sleep';
44

src/tests/unit-tests/data-structures/queue.test.ts src/tests/data-structures/queue.test.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { Queue } from '../../../data-structures/queue';
1+
import { Queue } from '../../data-structures/queue';
22

33
describe('Queue', () => {
44
it('should create an instance', () => {

src/tests/unit-tests/data-structures/singly-linked-list.test.ts src/tests/data-structures/singly-linked-list.test.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { SinglyLinkedList } from '../../../data-structures/singly-linked-list';
1+
import { SinglyLinkedList } from '../../data-structures/singly-linked-list';
22

33
describe('SinglyLinkedList', () => {
44
it('should create an instance', () => {

src/tests/data-structures/stack-with-ll.test.ts

Whitespace-only changes.
+60
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
import { Stack } from '../../data-structures/stack';
2+
3+
describe('Stack', () => {
4+
it('should create an instance', () => {
5+
const stack = new Stack(10);
6+
expect(stack).toBeInstanceOf(Stack);
7+
expect(stack.length).toBe(0);
8+
expect(stack.read()).toBeUndefined();
9+
});
10+
11+
it('should push and pop values', () => {
12+
const stack = new Stack(10);
13+
stack.insert(1);
14+
expect(stack.length).toBe(1);
15+
expect(stack.delete()).toBe(1);
16+
expect(stack.length).toBe(0);
17+
stack.insert(1);
18+
stack.insert(2);
19+
expect(stack.read()).toBe(2);
20+
expect(stack.length).toBe(2);
21+
22+
expect(stack.delete()).toBe(2);
23+
expect(stack.read()).toBe(1);
24+
expect(stack.length).toBe(1);
25+
expect(stack.delete()).toBe(1);
26+
expect(stack.length).toBe(0);
27+
expect(stack.read()).toBe(undefined);
28+
});
29+
30+
it('should throw error for overflow or underflow', () => {
31+
const stack = new Stack(3);
32+
expect(stack.isFull()).toBe(false);
33+
stack.insert(1);
34+
stack.insert(2);
35+
stack.insert(3);
36+
expect(stack.isFull()).toBe(true);
37+
expect(() => {
38+
stack.insert(4);
39+
}).toThrowError('Stack is full');
40+
expect(stack.length).toBe(3);
41+
expect(stack.read()).toBe(3);
42+
expect(stack.delete()).toBe(3);
43+
stack.insert(3);
44+
expect(() => {
45+
stack.insert(4);
46+
}).toThrowError('Stack is full');
47+
expect(stack.length).toBe(3);
48+
expect(stack.read()).toBe(3);
49+
expect(stack.isEmpty()).toBe(false);
50+
stack.delete();
51+
stack.delete();
52+
stack.delete();
53+
expect(stack.isEmpty()).toBe(true);
54+
expect(() => {
55+
stack.delete();
56+
}).toThrowError('Stack is empty');
57+
expect(stack.length).toBe(0);
58+
expect(stack.read()).toBeUndefined();
59+
});
60+
});

src/tests/helpers/array.test.ts

+17
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
import { createArrayOfSize } from '../../helpers/array';
2+
3+
describe('array helpers', () => {
4+
it('createArrayOfSize', () => {
5+
const array = createArrayOfSize<number>(10, 0);
6+
expect(array.length).toBe(10);
7+
expect(array[0]).toBe(0);
8+
expect(array[9]).toBe(0);
9+
expect(array).toEqual([0, 0, 0, 0, 0, 0, 0, 0, 0, 0]);
10+
11+
const array2 = createArrayOfSize<number | undefined>(10, undefined);
12+
expect(array2.length).toBe(10);
13+
expect(array2[0]).toBe(undefined);
14+
expect(array2[9]).toBe(undefined);
15+
expect(array2).toEqual([undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined]);
16+
});
17+
});

src/tests/unit-tests/data-structures/sized-stack.test.ts

-30
This file was deleted.

src/tests/unit-tests/data-structures/stack.test.ts

-31
This file was deleted.

wallaby.js

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
module.exports = function () {
22
return {
3-
files: ['src/**/*.ts', '!src/tests/**/*.test.ts', 'src/data/*.txt'],
4-
tests: ['src/tests/unit-tests/**/*.test.ts'],
3+
files: ['src/**/*.ts', '!src/tests/**/*.test.ts'],
4+
tests: ['src/tests/**/*.test.ts'],
55
env: {
66
type: 'node',
77
},

0 commit comments

Comments
 (0)