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 e5e2a43

Browse files
committed
Add min and max binary heap + tests
1 parent 300fd4a commit e5e2a43

File tree

10 files changed

+299
-24
lines changed

10 files changed

+299
-24
lines changed

‎.gitignore

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,3 @@
11
node_modules/
2-
.env
2+
.env
3+
.vscode/

‎.vscode/launch.json

Whitespace-only changes.

‎dist/datastructures/BinaryHeap.js

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
"use strict";
2+
Object.defineProperty(exports, "__esModule", { value: true });
3+
class BinaryHeap {
4+
constructor(type) {
5+
this.values = [];
6+
this.type = type;
7+
}
8+
insert(value) {
9+
this.values.push(value);
10+
let valueIndex = this.values.length - 1;
11+
const helper = () => {
12+
let parentIndex = Math.floor((valueIndex - 1) / 2);
13+
if (this.type === 'max' && this.values[parentIndex] < value
14+
|| this.type === 'min' && this.values[parentIndex] > value) {
15+
[this.values[valueIndex], this.values[parentIndex]] = [this.values[parentIndex], this.values[valueIndex]]; // swap parent and larger child
16+
valueIndex = parentIndex;
17+
helper();
18+
}
19+
};
20+
helper();
21+
return this.values;
22+
}
23+
}
24+
exports.default = BinaryHeap;

‎dist/datastructures/BinaryHeap.test.js

Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
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 BinaryHeap_1 = __importDefault(require("./BinaryHeap"));
7+
let MaxBH = new BinaryHeap_1.default('max');
8+
let MinBH = new BinaryHeap_1.default('min');
9+
beforeEach(() => {
10+
MaxBH = new BinaryHeap_1.default('max');
11+
MinBH = new BinaryHeap_1.default('min');
12+
});
13+
describe('max binary heap base functionality', () => {
14+
test('insert method exists', () => {
15+
expect(typeof MaxBH.insert).toBe('function');
16+
});
17+
});
18+
describe('max binary heap insert method tests', () => {
19+
test('can insert value as root', () => {
20+
MaxBH.insert(100);
21+
expect(MaxBH.values).toEqual([100]);
22+
});
23+
test('inserting a small number first then larger will result in the larger value bubbling up', () => {
24+
MaxBH.insert(25);
25+
MaxBH.insert(100);
26+
expect(MaxBH.values).toEqual([100, 25]);
27+
});
28+
test('inserting many small numbers first then larger will result in the larger value bubbling up to root, and a proper max binary heap', () => {
29+
MaxBH.insert(25);
30+
MaxBH.insert(30);
31+
MaxBH.insert(35);
32+
MaxBH.insert(40);
33+
MaxBH.insert(45);
34+
MaxBH.insert(50);
35+
MaxBH.insert(60);
36+
MaxBH.insert(100);
37+
expect(MaxBH.values).toEqual([100, 60, 50, 40, 35, 30, 45, 25]);
38+
});
39+
});
40+
describe('min binary heap insert method tests', () => {
41+
test('can insert value as root', () => {
42+
MinBH.insert(100);
43+
expect(MinBH.values).toEqual([100]);
44+
});
45+
test('inserting a large number first then smaller will result in the larger value bubbling up', () => {
46+
MinBH.insert(100);
47+
MinBH.insert(25);
48+
expect(MinBH.values).toEqual([25, 100]);
49+
});
50+
test('inserting many small numbers first then larger will result in the larger value bubbling up to root, and a proper max binary heap', () => {
51+
MinBH.insert(100);
52+
MinBH.insert(95);
53+
MinBH.insert(90);
54+
MinBH.insert(85);
55+
MinBH.insert(80);
56+
MinBH.insert(25);
57+
MinBH.insert(20);
58+
MinBH.insert(1);
59+
MinBH.insert(0);
60+
console.log(MinBH.values);
61+
expect(MinBH.values).toEqual([0, 1, 25, 20, 90, 95, 80, 100, 85]);
62+
});
63+
});

‎dist/datastructures/BinarySearchTree.js

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,9 @@ class BinarySearchTree {
5454
return startingNode;
5555
}
5656
BFS(cbFn, startingNode = this.root) {
57+
// this probably should be refactored to a simpler solution where
58+
// the dequeueing happens after the whole tree has been place
59+
// in the queue.
5760
if (startingNode === null)
5861
return null;
5962
const queue = new Queue_1.default();
@@ -98,6 +101,22 @@ class BinarySearchTree {
98101
if (node.left)
99102
helper(node.left);
100103
}
104+
if (order === 'preorder') {
105+
if (cbFn)
106+
cbFn(node);
107+
if (node.left)
108+
helper(node.left);
109+
if (node.right)
110+
helper(node.right);
111+
}
112+
if (order === 'postorder') {
113+
if (node.left)
114+
helper(node.left);
115+
if (node.right)
116+
helper(node.right);
117+
if (cbFn)
118+
cbFn(node);
119+
}
101120
};
102121
helper();
103122
}

‎dist/datastructures/BinarySearchTree.test.js

Lines changed: 43 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ var __importStar = (this && this.__importStar) || function (mod) {
88
};
99
Object.defineProperty(exports, "__esModule", { value: true });
1010
const BinarySearchTree_1 = __importStar(require("./BinarySearchTree"));
11-
function populateTree(tree) {
11+
function populateTree1(tree) {
1212
BST.insert(5);
1313
BST.insert(3);
1414
BST.insert(8);
@@ -17,6 +17,14 @@ function populateTree(tree) {
1717
BST.insert(1);
1818
BST.insert(9);
1919
}
20+
function populateTree2(tree) {
21+
BST.insert(10);
22+
BST.insert(6);
23+
BST.insert(15);
24+
BST.insert(8);
25+
BST.insert(20);
26+
BST.insert(3);
27+
}
2028
let BST = new BinarySearchTree_1.default();
2129
beforeEach(() => BST = new BinarySearchTree_1.default());
2230
describe('basic binary search tree functionality', () => {
@@ -40,14 +48,14 @@ describe('basic binary search tree functionality', () => {
4048
expect((_b = (_a = BST.root) === null || _a === void 0 ? void 0 : _a.left) === null || _b === void 0 ? void 0 : _b.data).toBe(1);
4149
expect((_d = (_c = BST.root) === null || _c === void 0 ? void 0 : _c.right) === null || _d === void 0 ? void 0 : _d.data).toBe(10);
4250
});
51+
});
52+
describe('insertion', () => {
4353
test('Insert method exists', () => {
4454
expect(typeof BST.insert).toBe('function');
4555
});
46-
});
47-
describe('insertion', () => {
4856
test('insert method works by inserting in order (left to right ascending)', () => {
4957
var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q, _r, _s;
50-
populateTree(BST);
58+
populateTree1(BST);
5159
expect((_a = BST.root) === null || _a === void 0 ? void 0 : _a.data).toBe(5);
5260
expect((_c = (_b = BST.root) === null || _b === void 0 ? void 0 : _b.left) === null || _c === void 0 ? void 0 : _c.data).toBe(3);
5361
expect((_e = (_d = BST.root) === null || _d === void 0 ? void 0 : _d.right) === null || _e === void 0 ? void 0 : _e.data).toBe(8);
@@ -77,7 +85,7 @@ describe('binary search', () => {
7785
});
7886
test('searching a populated tree', () => {
7987
var _a, _b, _c, _d, _e, _f, _g;
80-
populateTree(BST);
88+
populateTree1(BST);
8189
expect((_a = BST.find(1)) === null || _a === void 0 ? void 0 : _a.data).toBe(1);
8290
expect(BST.find(2)).toBeNull();
8391
expect((_b = BST.find(3)) === null || _b === void 0 ? void 0 : _b.data).toBe(3);
@@ -91,27 +99,52 @@ describe('binary search', () => {
9199
});
92100
describe('depth first search', () => {
93101
test('can log a populated tree in ascending order', () => {
94-
populateTree(BST);
102+
populateTree1(BST);
95103
let ascendingArray = [];
96104
BST.DFS((node) => { ascendingArray.push(node.data); });
97105
expect(ascendingArray).toEqual([1, 3, 4, 5, 6, 8, 9]);
98106
});
99107
test('can log a populated tree in descending order', () => {
100-
populateTree(BST);
108+
populateTree1(BST);
101109
let descendingArray = [];
102110
BST.DFS((node) => descendingArray.push(node.data), BST.root, { order: 'descending' });
103111
expect(descendingArray).toEqual([9, 8, 6, 5, 4, 3, 1]);
104112
});
113+
test('preorder DFS working', () => {
114+
populateTree2(BST);
115+
const array = [];
116+
BST.DFS((node) => array.push(node.data), BST.root, { order: 'preorder' });
117+
expect(array).toEqual([10, 6, 3, 8, 15, 20]);
118+
});
119+
test('postorder DFS working', () => {
120+
populateTree2(BST);
121+
const array = [];
122+
BST.DFS((node) => array.push(node.data), BST.root, { order: 'postorder' });
123+
expect(array).toEqual([3, 8, 6, 20, 15, 10]);
124+
});
105125
});
106126
describe('breadth first search', () => {
107127
test('BFS exists', () => {
108128
expect(BST.BFS(null, BST.root)).toBeNull();
109129
});
110-
test('BFS can print out contents of a basic tree', () => {
130+
test('BFS can accurately print out contents of a basic tree 1', () => {
131+
populateTree2(BST);
111132
let array = [];
112-
populateTree(BST);
113133
BST.BFS((node) => array.push(node.data));
114-
console.log(array);
134+
expect(array).toEqual([10, 6, 15, 3, 8, 20]);
135+
});
136+
test('BFS can accurately print out contents of a basic tree 2', () => {
137+
var _a;
138+
let array = [];
139+
populateTree1(BST);
140+
BST.BFS((node) => array.push(node.data));
115141
expect(array).toEqual([5, 3, 8, 1, 4, 6, 9]);
142+
BST.insert(7);
143+
// 7 should be passed down to lowest level of tree beneath 6
144+
array = [];
145+
BST.BFS((node) => array.push(node.data));
146+
const sixNode = BST.find(6);
147+
expect((_a = sixNode === null || sixNode === void 0 ? void 0 : sixNode.right) === null || _a === void 0 ? void 0 : _a.data).toBe(7);
148+
expect(array).toEqual([5, 3, 8, 1, 4, 6, 9, 7]);
116149
});
117150
});

‎src/datastructures/BinaryHeap.test.ts

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
import BinaryHeap from './BinaryHeap';
2+
3+
let MaxBH = new BinaryHeap<number>('max');
4+
let MinBH = new BinaryHeap<number>('min');
5+
beforeEach(() => {
6+
MaxBH = new BinaryHeap<number>('max');
7+
MinBH = new BinaryHeap<number>('min');
8+
});
9+
10+
describe('max binary heap base functionality', () => {
11+
test('insert method exists', () => {
12+
expect(typeof MaxBH.insert).toBe('function');
13+
});
14+
})
15+
16+
describe('max binary heap insert method tests', () => {
17+
test('can insert value as root', () => {
18+
MaxBH.insert(100);
19+
expect(MaxBH.values).toEqual([100]);
20+
});
21+
test('inserting a small number first then larger will result in the larger value bubbling up', () => {
22+
MaxBH.insert(25);
23+
MaxBH.insert(100);
24+
expect(MaxBH.values).toEqual([100, 25]);
25+
})
26+
test('inserting many small numbers first then larger will result in the larger value bubbling up to root, and a proper max binary heap', () => {
27+
MaxBH.insert(25);
28+
MaxBH.insert(30);
29+
MaxBH.insert(35);
30+
MaxBH.insert(40);
31+
MaxBH.insert(45);
32+
MaxBH.insert(50);
33+
MaxBH.insert(60);
34+
MaxBH.insert(100);
35+
expect(MaxBH.values).toEqual([100, 60, 50, 40, 35, 30, 45, 25]);
36+
})
37+
})
38+
39+
describe('min binary heap insert method tests', () => {
40+
test('can insert value as root', () => {
41+
MinBH.insert(100);
42+
expect(MinBH.values).toEqual([100]);
43+
});
44+
test('inserting a large number first then smaller will result in the larger value bubbling up', () => {
45+
MinBH.insert(100);
46+
MinBH.insert(25);
47+
expect(MinBH.values).toEqual([25, 100]);
48+
})
49+
test('inserting many small numbers first then larger will result in the larger value bubbling up to root, and a proper max binary heap', () => {
50+
MinBH.insert(100);
51+
MinBH.insert(95);
52+
MinBH.insert(90);
53+
MinBH.insert(85);
54+
MinBH.insert(80);
55+
MinBH.insert(25);
56+
MinBH.insert(20);
57+
MinBH.insert(1);
58+
MinBH.insert(0);
59+
expect(MinBH.values).toEqual([0, 1, 25, 20, 90, 95, 80, 100, 85]);
60+
})
61+
})

‎src/datastructures/BinaryHeap.ts

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
interface BinaryHeap<T> {
2+
values: T[];
3+
type: 'min' | 'max';
4+
}
5+
6+
class BinaryHeap<T> {
7+
constructor(type: 'min' | 'max') {
8+
this.values = [];
9+
this.type = type;
10+
}
11+
12+
insert(value: T) {
13+
this.values.push(value);
14+
let valueIndex = this.values.length - 1;
15+
const helper = () => {
16+
let parentIndex = Math.floor((valueIndex - 1) / 2);
17+
if (this.type === 'max' && this.values[parentIndex] < value
18+
|| this.type === 'min' && this.values[parentIndex] > value) {
19+
[this.values[valueIndex], this.values[parentIndex]] = [this.values[parentIndex], this.values[valueIndex]]; // swap parent and larger child
20+
valueIndex = parentIndex;
21+
helper();
22+
}
23+
}
24+
helper();
25+
return this.values;
26+
}
27+
}
28+
29+
export default BinaryHeap;

0 commit comments

Comments
(0)

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