Skip to content

Commit 8da6754

Browse files
committed
Add Stack.
1 parent 159d489 commit 8da6754

File tree

9 files changed

+181
-40
lines changed

9 files changed

+181
-40
lines changed

README.md

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,9 @@
44

55
## Data Structures
66

7-
- [Linked List](https://github.com/trekhleb/javascript-algorithms/tree/master/src/data-structures/linked-list)
8-
- [Hash Table](https://github.com/trekhleb/javascript-algorithms/tree/master/src/data-structures/hash-table)
9-
- [Queue](https://github.com/trekhleb/javascript-algorithms/tree/master/src/data-structures/queue)
7+
1. [Linked List](https://github.com/trekhleb/javascript-algorithms/tree/master/src/data-structures/linked-list)
8+
2. [Queue](https://github.com/trekhleb/javascript-algorithms/tree/master/src/data-structures/queue)
9+
3. [Hash Table](https://github.com/trekhleb/javascript-algorithms/tree/master/src/data-structures/hash-table)
1010

1111
## Running Tests
1212

src/data-structures/linked-list/LinkedList.js

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -160,6 +160,23 @@ export default class LinkedList {
160160
return deletedTail;
161161
}
162162

163+
deleteHead() {
164+
if (!this.head) {
165+
return null;
166+
}
167+
168+
const deletedHead = this.head;
169+
170+
if (this.head.next) {
171+
this.head = this.head.next;
172+
} else {
173+
this.head = null;
174+
this.tail = null;
175+
}
176+
177+
return deletedHead;
178+
}
179+
163180
findByKey(key) {
164181
let currentNode = this.head;
165182

src/data-structures/linked-list/__test__/LinkedList.test.js

Lines changed: 62 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,8 @@ describe('LinkedList', () => {
4343
it('should delete node by value from linked list', () => {
4444
const linkedList = new LinkedList();
4545

46+
expect(linkedList.deleteByValue(5)).toBeNull();
47+
4648
linkedList.append({ value: 1 });
4749
linkedList.append({ value: 2 });
4850
linkedList.append({ value: 3 });
@@ -80,40 +82,85 @@ describe('LinkedList', () => {
8082
expect(linkedList.tail.toString()).toBe('2');
8183
});
8284

85+
it('should delete node by key from linked list', () => {
86+
const linkedList = new LinkedList();
87+
88+
expect(linkedList.deleteByKey('key')).toBeNull();
89+
90+
linkedList.append({ value: 1, key: 'test1' });
91+
linkedList.append({ value: 2, key: 'test2' });
92+
linkedList.append({ value: 3, key: 'test3' });
93+
linkedList.append({ value: 4, key: 'test4' });
94+
95+
const deletedNode1 = linkedList.deleteByKey('test2');
96+
expect(deletedNode1.key).toBe('test2');
97+
expect(linkedList.toString()).toBe('test1:1,test3:3,test4:4');
98+
99+
const deletedNode2 = linkedList.deleteByKey('test1');
100+
expect(deletedNode2.key).toBe('test1');
101+
expect(linkedList.toString()).toBe('test3:3,test4:4');
102+
103+
const deletedNode3 = linkedList.deleteByKey('test4');
104+
expect(deletedNode3.key).toBe('test4');
105+
expect(linkedList.toString()).toBe('test3:3');
106+
});
107+
83108
it('should delete linked list tail', () => {
84109
const linkedList = new LinkedList();
85110

86111
linkedList.append({ value: 1 });
87112
linkedList.append({ value: 2 });
113+
linkedList.append({ value: 3 });
88114

89115
expect(linkedList.head.toString()).toBe('1');
90-
expect(linkedList.tail.toString()).toBe('2');
116+
expect(linkedList.tail.toString()).toBe('3');
91117

92118
const deletedNode1 = linkedList.deleteTail();
93119

94-
expect(deletedNode1.value).toBe(2);
120+
expect(deletedNode1.value).toBe(3);
121+
expect(linkedList.toString()).toBe('1,2');
122+
expect(linkedList.head.toString()).toBe('1');
123+
expect(linkedList.tail.toString()).toBe('2');
124+
125+
const deletedNode2 = linkedList.deleteTail();
126+
127+
expect(deletedNode2.value).toBe(2);
95128
expect(linkedList.toString()).toBe('1');
96129
expect(linkedList.head.toString()).toBe('1');
97130
expect(linkedList.tail.toString()).toBe('1');
98131

99-
const deletedNode2 = linkedList.deleteTail();
132+
const deletedNode3 = linkedList.deleteTail();
100133

101-
expect(deletedNode2.value).toBe(1);
134+
expect(deletedNode3.value).toBe(1);
102135
expect(linkedList.toString()).toBe('');
103136
expect(linkedList.head).toBeNull();
104137
expect(linkedList.tail).toBeNull();
105138
});
106139

107-
it('should delete node by key from linked list', () => {
140+
it('should delete linked list head', () => {
108141
const linkedList = new LinkedList();
109142

110-
linkedList.append({ value: 1, key: 'test1' });
111-
linkedList.append({ value: 2, key: 'test2' });
112-
linkedList.append({ value: 3, key: 'test3' });
143+
expect(linkedList.deleteHead()).toBeNull();
144+
145+
linkedList.append({ value: 1 });
146+
linkedList.append({ value: 2 });
147+
148+
expect(linkedList.head.toString()).toBe('1');
149+
expect(linkedList.tail.toString()).toBe('2');
113150

114-
const deletedNode = linkedList.deleteByKey('test2');
115-
expect(deletedNode.key).toBe('test2');
116-
expect(linkedList.toString()).toBe('test1:1,test3:3');
151+
const deletedNode1 = linkedList.deleteHead();
152+
153+
expect(deletedNode1.value).toBe(1);
154+
expect(linkedList.toString()).toBe('2');
155+
expect(linkedList.head.toString()).toBe('2');
156+
expect(linkedList.tail.toString()).toBe('2');
157+
158+
const deletedNode2 = linkedList.deleteHead();
159+
160+
expect(deletedNode2.value).toBe(2);
161+
expect(linkedList.toString()).toBe('');
162+
expect(linkedList.head).toBeNull();
163+
expect(linkedList.tail).toBeNull();
117164
});
118165

119166
it('should append unique nodes', () => {
@@ -122,13 +169,16 @@ describe('LinkedList', () => {
122169
linkedList.appendUnique({ value: 1, key: 'test1' });
123170
linkedList.appendUnique({ value: 2, key: 'test2' });
124171
linkedList.appendUnique({ value: 3, key: 'test2' });
172+
linkedList.appendUnique({ value: 5, key: 'test1' });
125173

126-
expect(linkedList.toString()).toBe('test1:1,test2:3');
174+
expect(linkedList.toString()).toBe('test1:5,test2:3');
127175
});
128176

129177
it('should find node by its key', () => {
130178
const linkedList = new LinkedList();
131179

180+
expect(linkedList.findByKey('test')).toBeNull();
181+
132182
linkedList.appendUnique({ value: 1, key: 'test1' });
133183
linkedList.appendUnique({ value: 2, key: 'test2' });
134184
linkedList.appendUnique({ value: 3, key: 'test3' });

src/data-structures/queue/Queue.js

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -10,19 +10,19 @@ export default class Queue {
1010
}
1111

1212
peek() {
13-
if (!this.linkedList.tail) {
13+
if (!this.linkedList.head) {
1414
return null;
1515
}
1616

17-
return this.linkedList.tail.value;
17+
return this.linkedList.head.value;
1818
}
1919

20-
add(value) {
20+
enqueue(value) {
2121
this.linkedList.append({ value });
2222
}
2323

24-
remove() {
25-
const removedTail = this.linkedList.deleteTail();
26-
return removedTail ? removedTail.value : null;
24+
dequeue() {
25+
const removedHead = this.linkedList.deleteHead();
26+
return removedHead ? removedHead.value : null;
2727
}
2828
}
Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,2 @@
11
# Queue
22

3-
|Operation |Complexity |
4-
|---------------------------|-------------------|
5-
|Find |O() |
6-
|Insert/delete at beginning |O() |
7-
|Insert/delete in middle |O() |
8-
|Insert/delete at end |O() |

src/data-structures/queue/__test__/Queue.test.js

Lines changed: 13 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -7,11 +7,11 @@ describe('Queue', () => {
77
expect(queue.linkedList).not.toBeNull();
88
});
99

10-
it('should add data to queue', () => {
10+
it('should enqueue data to queue', () => {
1111
const queue = new Queue();
1212

13-
queue.add(1);
14-
queue.add(2);
13+
queue.enqueue(1);
14+
queue.enqueue(2);
1515

1616
expect(queue.linkedList.toString()).toBe('1,2');
1717
});
@@ -21,31 +21,31 @@ describe('Queue', () => {
2121

2222
expect(queue.peek()).toBeNull();
2323

24-
queue.add(1);
25-
queue.add(2);
24+
queue.enqueue(1);
25+
queue.enqueue(2);
2626

27-
expect(queue.peek()).toBe(2);
28-
expect(queue.peek()).toBe(2);
27+
expect(queue.peek()).toBe(1);
28+
expect(queue.peek()).toBe(1);
2929
});
3030

3131
it('should check if queue is empty', () => {
3232
const queue = new Queue();
3333

3434
expect(queue.isEmpty()).toBeTruthy();
3535

36-
queue.add(1);
36+
queue.enqueue(1);
3737

3838
expect(queue.isEmpty()).toBeFalsy();
3939
});
4040

41-
it('should remove from empty', () => {
41+
it('should dequeue from queue in FIFO order', () => {
4242
const queue = new Queue();
4343

44-
queue.add(1);
45-
queue.add(2);
44+
queue.enqueue(1);
45+
queue.enqueue(2);
4646

47-
expect(queue.remove()).toBe(2);
48-
expect(queue.remove()).toBe(1);
47+
expect(queue.dequeue()).toBe(1);
48+
expect(queue.dequeue()).toBe(2);
4949
expect(queue.isEmpty()).toBeTruthy();
5050
});
5151
});
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
# Queue

src/data-structures/stack/Stack.js

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
import LinkedList from '../linked-list/LinkedList';
2+
3+
export default class Stack {
4+
constructor() {
5+
this.linkedList = new LinkedList();
6+
}
7+
8+
isEmpty() {
9+
return !this.linkedList.tail;
10+
}
11+
12+
peek() {
13+
if (!this.linkedList.tail) {
14+
return null;
15+
}
16+
17+
return this.linkedList.tail.value;
18+
}
19+
20+
push(value) {
21+
this.linkedList.append({ value });
22+
}
23+
24+
pop() {
25+
const removedTail = this.linkedList.deleteTail();
26+
return removedTail ? removedTail.value : null;
27+
}
28+
}
Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
import Stack from '../Stack';
2+
3+
describe('Stack', () => {
4+
it('should create empty stack', () => {
5+
const stack = new Stack();
6+
expect(stack).not.toBeNull();
7+
expect(stack.linkedList).not.toBeNull();
8+
});
9+
10+
it('should stack data to stack', () => {
11+
const stack = new Stack();
12+
13+
stack.push(1);
14+
stack.push(2);
15+
16+
expect(stack.linkedList.toString()).toBe('1,2');
17+
});
18+
19+
it('should peek data from stack', () => {
20+
const stack = new Stack();
21+
22+
expect(stack.peek()).toBeNull();
23+
24+
stack.push(1);
25+
stack.push(2);
26+
27+
expect(stack.peek()).toBe(2);
28+
expect(stack.peek()).toBe(2);
29+
});
30+
31+
it('should check if stack is empty', () => {
32+
const stack = new Stack();
33+
34+
expect(stack.isEmpty()).toBeTruthy();
35+
36+
stack.push(1);
37+
38+
expect(stack.isEmpty()).toBeFalsy();
39+
});
40+
41+
it('should pop data from stack', () => {
42+
const stack = new Stack();
43+
44+
stack.push(1);
45+
stack.push(2);
46+
47+
expect(stack.pop()).toBe(2);
48+
expect(stack.pop()).toBe(1);
49+
expect(stack.isEmpty()).toBeTruthy();
50+
});
51+
});

0 commit comments

Comments
 (0)