Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit 99f807f

Browse files
committed
add Queue class, and requisite unit tests
1 parent 9f99008 commit 99f807f

File tree

8 files changed

+316
-7
lines changed

8 files changed

+316
-7
lines changed

‎dist/datastructures/DoublyLinkedList.js

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
44
};
55
Object.defineProperty(exports, "__esModule", { value: true });
66
const SinglyLinkedList_1 = __importDefault(require("./SinglyLinkedList"));
7+
const IndexError_1 = __importDefault(require("../utils/IndexError"));
78
class DoublyLinkedList extends SinglyLinkedList_1.default {
89
constructor() {
910
super();
@@ -54,7 +55,7 @@ class DoublyLinkedList extends SinglyLinkedList_1.default {
5455
else {
5556
// count backwards from tail
5657
if (!this.tail || (index > this.length - 1 || index < 0))
57-
returnnull;
58+
thrownewIndexError_1.default('list index out of range.');
5859
let counter = this.length - 1;
5960
let node = this.tail;
6061
while (counter > index) {

‎dist/datastructures/Queue.js

Lines changed: 86 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,86 @@
1+
"use strict";
2+
var __importDefault = (this && this.__importDefault) || function (mod) {
3+
return (mod && mod.__esModule) ? mod : { "default": mod };
4+
};
5+
Object.defineProperty(exports, "__esModule", { value: true });
6+
const Node_1 = __importDefault(require("./Node"));
7+
const IndexError_1 = __importDefault(require("../utils/IndexError"));
8+
class Queue {
9+
constructor() {
10+
this.enqueue = (value) => {
11+
const oldBack = this.back;
12+
const node = new Node_1.default(value);
13+
// add node to end of list
14+
// O(1) since we keep track of tail node
15+
if (!this.front || !this.back) {
16+
this.front = node;
17+
}
18+
else {
19+
this.back.next = node;
20+
}
21+
this.back = node;
22+
this._length++;
23+
node.prev = oldBack;
24+
return node;
25+
};
26+
this.dequeue = () => {
27+
if (this.front && this.front.next) {
28+
this.front.next.prev = null;
29+
}
30+
if (!this.front)
31+
return;
32+
const newFront = this.front.next;
33+
const oldFront = this.front;
34+
oldFront.next = null;
35+
this.front = newFront || null;
36+
if (this.length === 1)
37+
this.back = null;
38+
this._length--;
39+
return oldFront;
40+
};
41+
this.get = (index) => {
42+
if (index < (this.length / 2)) {
43+
// start at front
44+
if (!this.front || (index > this.length - 1 || index < 0))
45+
throw new IndexError_1.default('list index out of range.');
46+
let counter = 0;
47+
let node = this.front;
48+
while (counter < index) {
49+
if (!node.next)
50+
return null;
51+
node = node.next;
52+
counter++;
53+
}
54+
return node;
55+
}
56+
else {
57+
// count from back
58+
if (!this.back || (index > this.length - 1 || index < 0))
59+
throw new IndexError_1.default('list index out of range.');
60+
let counter = this.length - 1;
61+
let node = this.back;
62+
while (counter > index) {
63+
if (!node.prev)
64+
return null;
65+
node = node.prev;
66+
counter--;
67+
}
68+
return node;
69+
}
70+
};
71+
this.set = (value, index) => {
72+
const selectedNode = this.get(index);
73+
if (selectedNode) {
74+
selectedNode.data = value;
75+
}
76+
return selectedNode;
77+
};
78+
this._length = 0;
79+
this.back = null;
80+
this.front = null;
81+
}
82+
get length() {
83+
return this._length;
84+
}
85+
}
86+
exports.default = Queue;

‎dist/datastructures/Queue.test.js

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
"use strict";
2+
var __importDefault = (this && this.__importDefault) || function (mod) {
3+
return (mod && mod.__esModule) ? mod : { "default": mod };
4+
};
5+
Object.defineProperty(exports, "__esModule", { value: true });
6+
const Queue_1 = __importDefault(require("./Queue"));
7+
let queue = new Queue_1.default();
8+
beforeEach(() => queue = new Queue_1.default());
9+
describe('base functionality', () => {
10+
test('queue class exists', () => {
11+
expect(typeof queue).toBe('object');
12+
});
13+
test('enqueue method exists', () => {
14+
expect(queue.enqueue).toBeTruthy();
15+
});
16+
test('dequeue method exists', () => {
17+
expect(queue.dequeue).toBeTruthy();
18+
});
19+
test('get method exists', () => {
20+
expect(queue.get).toBeTruthy();
21+
});
22+
test('set method exists', () => {
23+
expect(queue.set).toBeTruthy();
24+
});
25+
test('enqueue method works', () => {
26+
var _a, _b;
27+
queue.enqueue('1');
28+
queue.enqueue('2');
29+
queue.enqueue('3');
30+
expect(queue).toHaveLength(3);
31+
expect((_a = queue.back) === null || _a === void 0 ? void 0 : _a.data).toBe('3');
32+
expect((_b = queue.front) === null || _b === void 0 ? void 0 : _b.data).toBe('1');
33+
});
34+
test('dequeue method works', () => {
35+
var _a, _b;
36+
expect(queue.dequeue()).toBeUndefined();
37+
queue.enqueue('1');
38+
queue.enqueue('2');
39+
queue.enqueue('3');
40+
queue.dequeue();
41+
expect(queue).toHaveLength(2);
42+
expect((_a = queue.back) === null || _a === void 0 ? void 0 : _a.data).toBe('3');
43+
expect((_b = queue.front) === null || _b === void 0 ? void 0 : _b.data).toBe('2');
44+
});
45+
test('get and set methods work', () => {
46+
var _a, _b;
47+
try {
48+
queue.set('Mad Hatter', 1);
49+
}
50+
catch (e) {
51+
expect(e).toBeTruthy();
52+
}
53+
queue.enqueue('March Hare');
54+
queue.set('The Dormouse', 0);
55+
queue.set('Alice', 0);
56+
expect((_a = queue.front) === null || _a === void 0 ? void 0 : _a.data).toBe('Alice');
57+
expect((_b = queue.back) === null || _b === void 0 ? void 0 : _b.data).toBe('Alice');
58+
expect(queue).toHaveLength(1);
59+
});
60+
});

‎dist/datastructures/Stack.test.js

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,19 +11,26 @@ describe('base functionality', () => {
1111
test('stack class exists', () => {
1212
expect(typeof stack).toBe('object');
1313
});
14-
test('can unshift onto stack', () => {
14+
test('can push onto stack', () => {
1515
stack.push(`push: 0`);
1616
expect(stack.head).toBeTruthy();
1717
expect(stack.tail).toBeTruthy();
1818
expect(stack.head.data).toBe(`push: 0`);
1919
expect(stack.tail.data).toBe(`push: 0`);
2020
});
21+
test(`popping from stack gets last item pushed`, () => {
22+
stack.push('Walrus');
23+
stack.push('Orca');
24+
stack.push('Leopard seal');
25+
const poppedNode = stack.pop();
26+
expect(poppedNode).toBeTruthy();
27+
expect(poppedNode.data).toBe('Leopard seal');
28+
});
2129
test('get value of node with get method', () => {
2230
var _a, _b;
2331
stack = SinglyLinkedList_test_1.fillListWithDummyData(stack);
2432
const thirdNodeFromTop = stack.get(2);
2533
expect(thirdNodeFromTop).toBe((_b = (_a = stack.head) === null || _a === void 0 ? void 0 : _a.next) === null || _b === void 0 ? void 0 : _b.next);
26-
// console.log(stack.get(5))
2734
});
2835
test('able to set value of a node by index (distance from the top)', () => {
2936
var _a;

‎src/datastructures/DoublyLinkedList.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import _Node from "./Node";
22
import SinglyLinkedList from './SinglyLinkedList';
3+
import IndexError from '../utils/IndexError';
34

45
class DoublyLinkedList<T> extends SinglyLinkedList<T> {
56
constructor() {
@@ -53,7 +54,7 @@ class DoublyLinkedList<T> extends SinglyLinkedList<T> {
5354
}
5455
else {
5556
// count backwards from tail
56-
if (!this.tail || (index > this.length - 1 || index < 0)) returnnull;
57+
if (!this.tail || (index > this.length - 1 || index < 0)) thrownewIndexError('list index out of range.');
5758
let counter = this.length - 1;
5859
let node = this.tail;
5960
while (counter > index) {

‎src/datastructures/Queue.test.ts

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
import randomRange from '../utils/randomRange';
2+
import { fillListWithDummyData } from './SinglyLinkedList.test';
3+
import { testTraversalDLL } from './DoublyLinkedList.test';
4+
import _Node from './Node';
5+
import Queue from './Queue';
6+
7+
let queue = new Queue<string>();
8+
beforeEach(() => queue = new Queue<string>());
9+
10+
describe('base functionality', () => {
11+
test('queue class exists', () => {
12+
expect(typeof queue).toBe('object')
13+
});
14+
test('enqueue method exists', () => {
15+
expect(queue.enqueue).toBeTruthy()
16+
});
17+
test('dequeue method exists', () => {
18+
expect(queue.dequeue).toBeTruthy()
19+
});
20+
test('get method exists', () => {
21+
expect(queue.get).toBeTruthy()
22+
});
23+
test('set method exists', () => {
24+
expect(queue.set).toBeTruthy()
25+
});
26+
test('enqueue method works', () => {
27+
queue.enqueue('1');
28+
queue.enqueue('2');
29+
queue.enqueue('3');
30+
expect(queue).toHaveLength(3);
31+
expect(queue.back?.data).toBe('3');
32+
expect(queue.front?.data).toBe('1');
33+
});
34+
test('dequeue method works', () => {
35+
expect(queue.dequeue()).toBeUndefined();
36+
queue.enqueue('1');
37+
queue.enqueue('2');
38+
queue.enqueue('3');
39+
queue.dequeue();
40+
expect(queue).toHaveLength(2);
41+
expect(queue.back?.data).toBe('3');
42+
expect(queue.front?.data).toBe('2');
43+
});
44+
45+
test('get and set methods work', () => {
46+
try {
47+
queue.set('Mad Hatter', 1);
48+
}
49+
catch (e) {
50+
expect(e).toBeTruthy();
51+
}
52+
queue.enqueue('March Hare');
53+
queue.set('The Dormouse', 0);
54+
queue.set('Alice', 0);
55+
expect(queue.front?.data).toBe('Alice');
56+
expect(queue.back?.data).toBe('Alice');
57+
expect(queue).toHaveLength(1);
58+
})
59+
})

‎src/datastructures/Queue.ts

Lines changed: 88 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,88 @@
1+
import _Node from './Node';
2+
import IndexError from '../utils/IndexError';
3+
4+
interface Queue<T> {
5+
front: null | _Node<T>;
6+
back: null | _Node<T>;
7+
}
8+
9+
10+
class Queue<T> {
11+
private _length: number;
12+
constructor() {
13+
this._length = 0;
14+
this.back = null;
15+
this.front = null;
16+
}
17+
18+
public get length(): number {
19+
return this._length;
20+
}
21+
22+
enqueue = (value: T): _Node<T> => {
23+
const oldBack = this.back;
24+
const node = new _Node(value);
25+
// add node to end of list
26+
// O(1) since we keep track of tail node
27+
if (!this.front || !this.back) {
28+
this.front = node;
29+
} else {
30+
this.back.next = node;
31+
}
32+
this.back = node;
33+
this._length++;
34+
node.prev = oldBack;
35+
return node;
36+
}
37+
38+
dequeue = (): _Node<T> | void => {
39+
if (this.front && this.front.next) {
40+
this.front.next.prev = null;
41+
}
42+
if (!this.front) return;
43+
const newFront = this.front.next;
44+
const oldFront = this.front;
45+
oldFront.next = null;
46+
this.front = newFront || null;
47+
if (this.length === 1) this.back = null;
48+
this._length--;
49+
return oldFront;
50+
}
51+
52+
get = (index: number): _Node<T> | null => {
53+
if (index < (this.length / 2)) {
54+
// start at front
55+
if (!this.front || (index > this.length - 1 || index < 0)) throw new IndexError('list index out of range.');
56+
let counter = 0;
57+
let node = this.front;
58+
while (counter < index) {
59+
if (!node.next) return null;
60+
node = node.next;
61+
counter++;
62+
}
63+
return node;
64+
}
65+
else {
66+
// count from back
67+
if (!this.back || (index > this.length - 1 || index < 0)) throw new IndexError('list index out of range.');
68+
let counter = this.length - 1;
69+
let node = this.back;
70+
while (counter > index) {
71+
if (!node.prev) return null;
72+
node = node.prev;
73+
counter--;
74+
}
75+
return node;
76+
}
77+
}
78+
79+
set = (value: T, index: number): _Node<T> | null => {
80+
const selectedNode = this.get(index);
81+
if (selectedNode) {
82+
selectedNode.data = value;
83+
}
84+
return selectedNode;
85+
}
86+
}
87+
88+
export default Queue;

‎src/datastructures/Stack.test.ts

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
1-
import randomRange from '../utils/randomRange';
21
import { fillListWithDummyData, testTraversalSLL } from './SinglyLinkedList.test';
32
import Stack from './Stack';
3+
import _Node from './Node';
44

55
let stack = new Stack<string>();
66
beforeEach(() => stack = new Stack<string>());
@@ -9,18 +9,25 @@ describe('base functionality', () => {
99
test('stack class exists', () => {
1010
expect(typeof stack).toBe('object');
1111
});
12-
test('can unshift onto stack', () => {
12+
test('can push onto stack', () => {
1313
stack.push(`push: 0`);
1414
expect(stack.head).toBeTruthy();
1515
expect(stack.tail).toBeTruthy();
1616
expect(stack.head!.data).toBe(`push: 0`)
1717
expect(stack.tail!.data).toBe(`push: 0`);
1818
});
19+
test(`popping from stack gets last item pushed`, () => {
20+
stack.push('Walrus');
21+
stack.push('Orca');
22+
stack.push('Leopard seal');
23+
const poppedNode = stack.pop() as _Node<string>;
24+
expect(poppedNode).toBeTruthy();
25+
expect(poppedNode.data).toBe('Leopard seal')
26+
})
1927
test('get value of node with get method', () => {
2028
stack = fillListWithDummyData(stack);
2129
const thirdNodeFromTop = stack.get(2);
2230
expect(thirdNodeFromTop).toBe(stack.head?.next?.next)
23-
// console.log(stack.get(5))
2431
})
2532
test('able to set value of a node by index (distance from the top)', () => {
2633
stack = fillListWithDummyData(stack);

0 commit comments

Comments
(0)

AltStyle によって変換されたページ (->オリジナル) /