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 683c8fe

Browse files
committed
add find & depth first search (in order and reverse in order implemented so far)
1 parent c2c3bbc commit 683c8fe

File tree

4 files changed

+228
-28
lines changed

4 files changed

+228
-28
lines changed

‎dist/datastructures/BinarySearchTree.js

Lines changed: 56 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ class BinarySearchTree {
2020
return node;
2121
}
2222
let targetNode = this.root;
23-
while (targetNode) {
23+
while (true) {
2424
if (node.value < targetNode.value) {
2525
if (!targetNode.left) {
2626
targetNode.left = node;
@@ -36,7 +36,61 @@ class BinarySearchTree {
3636
targetNode = targetNode.right;
3737
}
3838
}
39-
return node;
39+
}
40+
find(value, startingNode = this.root) {
41+
if (!startingNode)
42+
return null;
43+
if (value < startingNode.value) {
44+
return this.find(value, startingNode.left);
45+
}
46+
if (value > startingNode.value) {
47+
return this.find(value, startingNode.right);
48+
}
49+
// found!
50+
return startingNode;
51+
}
52+
DFS(startingNode = this.root, options = { order: 'ascending' }) {
53+
if (startingNode === null)
54+
return null;
55+
const array = [];
56+
const helper = (node = startingNode, options = { order: 'ascending' }) => {
57+
const { order } = options;
58+
if (order === 'ascending') {
59+
if (node.left)
60+
helper(node.left);
61+
array.push(node.value);
62+
if (node.right)
63+
helper(node.right);
64+
}
65+
if (order === 'descending') {
66+
if (node.right)
67+
helper(node.right, { order: 'descending' });
68+
array.push(node.value);
69+
if (node.left)
70+
helper(node.left, { order: 'descending' });
71+
}
72+
};
73+
helper(startingNode, options);
74+
return array;
75+
}
76+
logTree(startingNode = this.root, options = { order: 'ascending' }) {
77+
if (!startingNode)
78+
return console.log(null);
79+
const { order } = options;
80+
if (order === 'ascending') {
81+
if (startingNode.left)
82+
this.logTree(startingNode.left);
83+
console.log(startingNode.value);
84+
if (startingNode.right)
85+
this.logTree(startingNode.right);
86+
}
87+
if (order === 'descending') {
88+
if (startingNode.right)
89+
return this.logTree(startingNode.right, { order: 'descending' });
90+
console.log(startingNode.value);
91+
if (startingNode.left)
92+
return this.logTree(startingNode.left, { order: 'descending' });
93+
}
4094
}
4195
}
4296
exports.default = BinarySearchTree;

‎dist/datastructures/BinarySearchTree.test.js

Lines changed: 59 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,15 @@ 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) {
12+
BST.insert(5);
13+
BST.insert(3);
14+
BST.insert(8);
15+
BST.insert(4);
16+
BST.insert(6);
17+
BST.insert(1);
18+
BST.insert(9);
19+
}
1120
let BST = new BinarySearchTree_1.default();
1221
beforeEach(() => BST = new BinarySearchTree_1.default());
1322
describe('basic binary search tree functionality', () => {
@@ -34,21 +43,62 @@ describe('basic binary search tree functionality', () => {
3443
test('Insert method exists', () => {
3544
expect(typeof BST.insert).toBe('function');
3645
});
46+
});
47+
describe('insertion', () => {
3748
test('insert method works by inserting in order (left to right ascending)', () => {
3849
var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q, _r, _s;
39-
BST.insert(5);
50+
populateTree(BST);
4051
expect((_a = BST.root) === null || _a === void 0 ? void 0 : _a.value).toBe(5);
41-
BST.insert(3);
4252
expect((_c = (_b = BST.root) === null || _b === void 0 ? void 0 : _b.left) === null || _c === void 0 ? void 0 : _c.value).toBe(3);
43-
BST.insert(7);
44-
expect((_e = (_d = BST.root) === null || _d === void 0 ? void 0 : _d.right) === null || _e === void 0 ? void 0 : _e.value).toBe(7);
45-
BST.insert(4);
53+
expect((_e = (_d = BST.root) === null || _d === void 0 ? void 0 : _d.right) === null || _e === void 0 ? void 0 : _e.value).toBe(8);
4654
expect((_h = (_g = (_f = BST.root) === null || _f === void 0 ? void 0 : _f.left) === null || _g === void 0 ? void 0 : _g.right) === null || _h === void 0 ? void 0 : _h.value).toBe(4);
47-
BST.insert(6);
4855
expect((_l = (_k = (_j = BST.root) === null || _j === void 0 ? void 0 : _j.right) === null || _k === void 0 ? void 0 : _k.left) === null || _l === void 0 ? void 0 : _l.value).toBe(6);
49-
BST.insert(1);
5056
expect((_p = (_o = (_m = BST.root) === null || _m === void 0 ? void 0 : _m.left) === null || _o === void 0 ? void 0 : _o.left) === null || _p === void 0 ? void 0 : _p.value).toBe(1);
51-
BST.insert(8);
52-
expect((_s = (_r = (_q = BST.root) === null || _q === void 0 ? void 0 : _q.right) === null || _r === void 0 ? void 0 : _r.right) === null || _s === void 0 ? void 0 : _s.value).toBe(8);
57+
expect((_s = (_r = (_q = BST.root) === null || _q === void 0 ? void 0 : _q.right) === null || _r === void 0 ? void 0 : _r.right) === null || _s === void 0 ? void 0 : _s.value).toBe(9);
58+
});
59+
test(`can insert multiple nodes of the same value and they'll bubble down the right`, () => {
60+
var _a, _b, _c, _d, _e, _f;
61+
BST.insert(1);
62+
BST.insert(1);
63+
BST.insert(1);
64+
expect((_a = BST.root) === null || _a === void 0 ? void 0 : _a.value).toBe(1);
65+
expect((_c = (_b = BST.root) === null || _b === void 0 ? void 0 : _b.right) === null || _c === void 0 ? void 0 : _c.value).toBe(1);
66+
expect((_f = (_e = (_d = BST.root) === null || _d === void 0 ? void 0 : _d.right) === null || _e === void 0 ? void 0 : _e.right) === null || _f === void 0 ? void 0 : _f.value).toBe(1);
67+
});
68+
});
69+
describe('binary search', () => {
70+
test('searching for a value in a empty tree returns null', () => {
71+
expect(BST.find(1)).toBeNull();
72+
});
73+
test('searching for a value which is the root value', () => {
74+
var _a;
75+
BST.insert(1);
76+
expect((_a = BST.find(1)) === null || _a === void 0 ? void 0 : _a.value).toBe(1);
77+
});
78+
test('searching a populated tree', () => {
79+
var _a, _b, _c, _d, _e, _f, _g;
80+
populateTree(BST);
81+
expect((_a = BST.find(1)) === null || _a === void 0 ? void 0 : _a.value).toBe(1);
82+
expect(BST.find(2)).toBeNull();
83+
expect((_b = BST.find(3)) === null || _b === void 0 ? void 0 : _b.value).toBe(3);
84+
expect((_c = BST.find(4)) === null || _c === void 0 ? void 0 : _c.value).toBe(4);
85+
expect((_d = BST.find(5)) === null || _d === void 0 ? void 0 : _d.value).toBe(5);
86+
expect((_e = BST.find(6)) === null || _e === void 0 ? void 0 : _e.value).toBe(6);
87+
expect(BST.find(7)).toBeNull();
88+
expect((_f = BST.find(8)) === null || _f === void 0 ? void 0 : _f.value).toBe(8);
89+
expect((_g = BST.find(9)) === null || _g === void 0 ? void 0 : _g.value).toBe(9);
90+
});
91+
});
92+
describe('depth first search', () => {
93+
test('can log an empty tree', () => {
94+
});
95+
test('can log a populated tree in ascending order', () => {
96+
populateTree(BST);
97+
expect(BST.DFS()).toEqual([1, 3, 4, 5, 6, 8, 9]);
98+
});
99+
test('can log a populated tree in descending order', () => {
100+
populateTree(BST);
101+
console.log(BST.DFS(BST.root, { order: 'descending' }));
102+
expect(BST.DFS(BST.root, { order: 'descending' })).toEqual([9, 8, 6, 5, 4, 3, 1]);
53103
});
54104
});
Lines changed: 66 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,44 +1,96 @@
11
import BinarySearchTree, { BinaryTreeNode } from './BinarySearchTree';
22

3+
function populateTree<T>(tree: BinarySearchTree<T>): void {
4+
BST.insert(5);
5+
BST.insert(3);
6+
BST.insert(8);
7+
BST.insert(4);
8+
BST.insert(6);
9+
BST.insert(1);
10+
BST.insert(9);
11+
}
12+
313
let BST = new BinarySearchTree<number>();
414
beforeEach(() => BST = new BinarySearchTree<number>());
515

616
describe('basic binary search tree functionality', () => {
717
test('Binary search tree exists', () => {
818
expect(BST).toBeTruthy();
9-
})
19+
});
1020
test('Tree root initiates as null', () => {
1121
expect(BST.root).toBeNull();
12-
})
22+
});
1323
test('Can add new root node to tree', () => {
1424
const node = new BinaryTreeNode(5);
1525
BST.root = node;
1626
expect(BST.root?.value).toBe(5);
17-
})
27+
});
1828
test('Can add left and right nodes to tree root manually', () => {
1929
BST.root = new BinaryTreeNode(5);
2030
BST.root.left = new BinaryTreeNode(1);
2131
BST.root.right = new BinaryTreeNode(10);
2232
expect(BST.root?.left?.value).toBe(1);
2333
expect(BST.root?.right?.value).toBe(10);
24-
})
34+
});
2535
test('Insert method exists', () => {
2636
expect(typeof BST.insert).toBe('function');
27-
})
37+
});
38+
})
39+
40+
describe('insertion', () => {
2841
test('insert method works by inserting in order (left to right ascending)', () => {
29-
BST.insert(5);
42+
populateTree(BST);
3043
expect(BST.root?.value).toBe(5);
31-
BST.insert(3);
3244
expect(BST.root?.left?.value).toBe(3);
33-
BST.insert(7);
34-
expect(BST.root?.right?.value).toBe(7);
35-
BST.insert(4);
45+
expect(BST.root?.right?.value).toBe(8);
3646
expect(BST.root?.left?.right?.value).toBe(4);
37-
BST.insert(6);
3847
expect(BST.root?.right?.left?.value).toBe(6);
39-
BST.insert(1);
4048
expect(BST.root?.left?.left?.value).toBe(1);
41-
BST.insert(8);
42-
expect(BST.root?.right?.right?.value).toBe(8);
49+
expect(BST.root?.right?.right?.value).toBe(9);
50+
});
51+
test(`can insert multiple nodes of the same value and they'll bubble down the right`, () => {
52+
BST.insert(1);
53+
BST.insert(1);
54+
BST.insert(1);
55+
expect(BST.root?.value).toBe(1);
56+
expect(BST.root?.right?.value).toBe(1);
57+
expect(BST.root?.right?.right?.value).toBe(1);
58+
});
59+
})
60+
61+
describe('binary search', () => {
62+
test('searching for a value in a empty tree returns null', () => {
63+
expect(BST.find(1)).toBeNull();
64+
})
65+
test('searching for a value which is the root value', () => {
66+
BST.insert(1);
67+
expect(BST.find(1)?.value).toBe(1);
68+
});
69+
test('searching a populated tree', () => {
70+
populateTree(BST);
71+
expect(BST.find(1)?.value).toBe(1);
72+
expect(BST.find(2)).toBeNull();
73+
expect(BST.find(3)?.value).toBe(3);
74+
expect(BST.find(4)?.value).toBe(4);
75+
expect(BST.find(5)?.value).toBe(5);
76+
expect(BST.find(6)?.value).toBe(6);
77+
expect(BST.find(7)).toBeNull();
78+
expect(BST.find(8)?.value).toBe(8);
79+
expect(BST.find(9)?.value).toBe(9);
80+
})
81+
})
82+
83+
describe('depth first search', () => {
84+
test('can log an empty tree', () => {
85+
86+
})
87+
test('can log a populated tree in ascending order', () => {
88+
populateTree(BST);
89+
expect(BST.DFS()).toEqual([1, 3, 4, 5, 6, 8, 9]);
90+
})
91+
test('can log a populated tree in descending order', () => {
92+
populateTree(BST);
93+
console.log(BST.DFS(BST.root, { order: 'descending' }));
94+
expect(BST.DFS(BST.root, { order: 'descending' })).toEqual([9, 8, 6, 5, 4, 3, 1]);
4395
})
4496
})

‎src/datastructures/BinarySearchTree.ts

Lines changed: 47 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ class BinaryTreeNode<T> {
88
constructor(value: T) {
99
this.left = null;
1010
this.right = null;
11-
this.value = value;
11+
this.value = valueasT;
1212
}
1313
}
1414

@@ -31,7 +31,7 @@ class BinarySearchTree<T> {
3131
return node;
3232
}
3333
let targetNode: BinaryTreeNode<T> = this.root;
34-
while (targetNode) {
34+
while (true) {
3535
if (node.value < targetNode.value) {
3636
if (!targetNode.left) {
3737
targetNode.left = node;
@@ -47,7 +47,51 @@ class BinarySearchTree<T> {
4747
targetNode = targetNode.right;
4848
}
4949
}
50-
return node;
50+
}
51+
find(value: T, startingNode: BinaryTreeNode<T> | null = this.root): BinaryTreeNode<T> | null {
52+
if (!startingNode) return null;
53+
if (value < startingNode.value) {
54+
return this.find(value, startingNode.left)
55+
}
56+
if (value > startingNode.value) {
57+
return this.find(value, startingNode.right)
58+
}
59+
// found!
60+
return startingNode;
61+
}
62+
63+
DFS(startingNode: BinaryTreeNode<T> | null = this.root, options = { order: 'ascending' }): T[] | null {
64+
if (startingNode === null) return null;
65+
const array: T[] = [];
66+
const helper = (node: BinaryTreeNode<T> = startingNode, options = { order: 'ascending' }): void => {
67+
const { order } = options;
68+
if (order === 'ascending') {
69+
if (node.left) helper(node.left);
70+
array.push(node.value);
71+
if (node.right) helper(node.right);
72+
}
73+
if (order === 'descending') {
74+
if (node.right) helper(node.right, { order: 'descending' });
75+
array.push(node.value);
76+
if (node.left) helper(node.left, { order: 'descending' });
77+
}
78+
};
79+
helper(startingNode, options);
80+
return array;
81+
}
82+
logTree(startingNode: BinaryTreeNode<T> | null = this.root, options = { order: 'ascending' }): void {
83+
if (!startingNode) return console.log(null);
84+
const { order } = options;
85+
if (order === 'ascending') {
86+
if (startingNode.left) this.logTree(startingNode.left);
87+
console.log(startingNode.value);
88+
if (startingNode.right) this.logTree(startingNode.right);
89+
}
90+
if (order === 'descending') {
91+
if (startingNode.right) return this.logTree(startingNode.right, { order: 'descending' });
92+
console.log(startingNode.value);
93+
if (startingNode.left) return this.logTree(startingNode.left, { order: 'descending' });
94+
}
5195
}
5296
}
5397

0 commit comments

Comments
(0)

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