Skip to content

Commit ef35827

Browse files
Implemented BFS (#11 IP)
1 parent 6b3daf1 commit ef35827

File tree

10 files changed

+177
-33
lines changed

10 files changed

+177
-33
lines changed

Algorithms/README.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,9 @@
2020
- [Unicode Characters | RapidTables](https://www.rapidtables.com/code/text/unicode-characters.html)
2121
- [The Big-O Algorithm Complexity Cheat Sheet](https://www.bigocheatsheet.com/ "Big O Cheat Sheet")
2222

23+
### Searching
24+
- [Space Complexity: BFS vs DFS](https://stackoverflow.com/questions/9844193/what-is-the-time-and-space-complexity-of-a-breadth-first-and-depth-first-tree-tr)
25+
2326
### Sorting
2427
- [Array.prototype.sort()](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/sort)
2528
- [Animated Sorting | Toptal](https://www.toptal.com/developers/sorting-algorithms)
Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
import BST from '../../Data-Structures/Trees/BinarySearchTree.ts';
2+
import Node from '../../Data-Structures/Trees/BinaryTreeNode.ts';
3+
import Queue from '../../Data-Structures/Sequential/Queue.ts';
4+
5+
function recursiveBFS(nodeQueue: Queue<Node>, nodesTraversed: Array<number>): Array<number> {
6+
if (nodeQueue.getLength() === 0) return nodesTraversed;
7+
8+
let currentNode: Node = nodeQueue.dequeue();
9+
nodesTraversed.push(currentNode.getValue());
10+
if (currentNode.hasLeft()) nodeQueue.enqueue(currentNode.getLeft());
11+
if (currentNode.hasRight()) nodeQueue.enqueue(currentNode.getRight());
12+
13+
return recursiveBFS(nodeQueue, nodesTraversed);
14+
}
15+
16+
function breadthFirstSearch(tree: BST) {
17+
const root = tree.getRoot();
18+
19+
if (!root) return false;
20+
21+
const nodesTraversed: number[] = [];
22+
const nodeQueue = new Queue<Node>();
23+
24+
nodeQueue.enqueue(root);
25+
26+
return recursiveBFS(nodeQueue, nodesTraversed);
27+
}
28+
29+
30+
//---------------------------------------------------------------------
31+
// ---------- MAIN PROGRAM ----------
32+
//---------------------------------------------------------------------
33+
if (import.meta.main) {
34+
35+
const tree = new BST();
36+
37+
// 9
38+
// 4 20
39+
// 1 6 15 170
40+
41+
tree.insert(9);
42+
tree.insert(4);
43+
tree.insert(6);
44+
tree.insert(20);
45+
tree.insert(170);
46+
tree.insert(15);
47+
tree.insert(1);
48+
49+
console.log(breadthFirstSearch(tree));
50+
51+
// RUN: deno run Algorithms/Recursion/BreadthFirstSearch.ts
52+
}
53+
54+
// --------------------------- Terminal Output: ---------------------------
55+
// [
56+
// 9, 4, 20, 1,
57+
// 6, 15, 170
58+
// ]

Algorithms/Searching/Basics.ts

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
var beasts = ['Centaur', 'Godzilla', 'Mosura', 'Minotaur', 'Hydra', 'Nessie'];
2+
3+
beasts.indexOf('Godzilla'); // Index: 1
4+
5+
beasts.findIndex(function(item){ // Index: 1
6+
return item === 'Godzilla';
7+
});
8+
9+
beasts.find(function(item){ // 'Godzilla'
10+
return item === 'Godzilla';
11+
});
12+
13+
beasts.includes('Godzilla'); // true
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
# Graph Traversal Use Cases
2+
3+
## Which traversal algorithm would be best for each situation? (BFS or DFS)
4+
5+
1) If you know a solution is not far from the root of the tree:
6+
7+
2) If the tree is very deep and solutions are rare,
8+
9+
3) If the tree is very wide:
10+
11+
4) If solutions are frequent but located deep in the tree
12+
13+
5) determining whether a path exists between two nodes
14+
15+
6) Finding the shortest path
16+
17+
## Answers
18+
1) BFS
19+
2) BFS (DFS will take longer)
20+
3) DFS (BFS is too memory intensive for wide trees)
21+
4) DFS
22+
5) DFS
23+
6) BFS

Algorithms/Sorting/InsertionSort.ts

Lines changed: 40 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -1,37 +1,51 @@
1-
import LinkedList from '../../Data-Structures/Linked-Lists/LinkedList.ts';
21
import { plant_families } from './Data/PlantFamilies.ts';
32

3+
function insertionSort(inputArr: number[] | string[]) {
44

5-
function insertionSort(inputArr: number[] | string[]): Array<any> {
6-
const sorted = new LinkedList<any>();
7-
8-
sorted.append(inputArr[0]);
9-
10-
for (let i=1; i < inputArr.length; ++i) {
11-
12-
let currentElement = inputArr[i];
13-
let currentNode = sorted.getHead();
14-
15-
// Element is less than the lowest value
16-
if (currentElement < sorted.getHeadValue()) {
17-
sorted.prepend(currentElement);
18-
}
19-
// Element is greater than the highest value
20-
else if (currentElement > sorted.getTailValue()) {
21-
sorted.append(currentElement)
5+
if (typeof inputArr[0] === 'number') {
6+
for (let i=0; i < inputArr.length; ++i) {
7+
if (inputArr[i] < inputArr[0]) {
8+
const element = inputArr.splice(i,1) as number[];
9+
// Move element to the first position
10+
(inputArr as number[]).unshift(element[0]);
11+
}
12+
else {
13+
// Only sort number smaller than preceding number
14+
if (inputArr[i] < inputArr[i-1]) {
15+
// Find where element's sorted position
16+
for (var j = 1; j < i; j++) {
17+
if (inputArr[i] >= inputArr[j-1] && inputArr[i] < inputArr[j]) {
18+
// Move element to the sorted spot
19+
inputArr.splice(j,0,inputArr.splice(i,1)[0] as number);
20+
}
21+
}
22+
}
23+
}
2224
}
23-
// Otherwise insert in its proper, sorted position
24-
else {
25-
for (let j=0; j < sorted.getLength()-1; ++j) {
26-
if (currentNode.getValue() < currentElement && currentNode.getNext().getValue() > currentElement) {
27-
sorted.insert(currentElement, j+1);
28-
break;
25+
}
26+
else if (typeof inputArr[0] === 'string') {
27+
for (let i=0; i < inputArr.length; ++i) {
28+
if (inputArr[i] < inputArr[0]) {
29+
const element = inputArr.splice(i,1) as string[];
30+
// Move element to the first position
31+
(inputArr as string[]).unshift(element[0]);
32+
}
33+
else {
34+
// Only sort number smaller than preceding number
35+
if (inputArr[i] < inputArr[i-1]) {
36+
// Find where element's sorted position
37+
for (var j = 1; j < i; j++) {
38+
if (inputArr[i] >= inputArr[j-1] && inputArr[i] < inputArr[j]) {
39+
// Move element to the sorted spot
40+
inputArr.splice(j,0,inputArr.splice(i,1)[0] as string);
41+
}
42+
}
2943
}
30-
currentNode = currentNode.getNext();
3144
}
3245
}
3346
}
34-
return sorted.toArray();
47+
48+
return inputArr;
3549
}
3650

3751
function executionTime(method: any): string {

Data-Structures/Linked-Lists/LinkedList.ts

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -15,10 +15,6 @@ export default class LinkedList<T> {
1515
return this.length;
1616
}
1717

18-
public getHead(): Node<T> | any {
19-
return this.head;
20-
}
21-
2218
public getHeadValue(): T | any {
2319
return this.head?.getValue();
2420
}

Data-Structures/Sequential/Queue.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ export default class Queue<T> {
4040
return true;
4141
}
4242

43-
public dequeue(): T | null {
43+
public dequeue(): T | any {
4444
if (!this.first) return null; // Edge case: Empty queue
4545

4646
if (this.length === 1) { // Edge case: Queue has 1 element, so a dequeue should reset the queue's state

Data-Structures/Trees/BinarySearchTree.ts

Lines changed: 29 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import BNode from './BinaryTreeNode.ts';
2+
import Queue from '../Sequential/Queue.ts';
23

34

45
export default class BinarySearchTree {
@@ -205,6 +206,24 @@ export default class BinarySearchTree {
205206
node.setRight(left);
206207
}
207208

209+
public breadthFirstSearch() {
210+
if (!this.root) return false;
211+
212+
let currentNode = this.root;
213+
let nodesTraversed = new Array();
214+
const nodeQueue: Queue<BNode> = new Queue();
215+
216+
nodeQueue.enqueue(currentNode);
217+
218+
while (nodeQueue.getLength() > 0) {
219+
currentNode = nodeQueue.dequeue();
220+
nodesTraversed.push(currentNode.getValue());
221+
if (currentNode.hasLeft()) nodeQueue.enqueue(currentNode.getLeft());
222+
if (currentNode.hasRight()) nodeQueue.enqueue(currentNode.getRight());
223+
}
224+
return nodesTraversed;
225+
}
226+
208227
public equalsQuantum(tree: BinarySearchTree): boolean {
209228
return JSON.stringify(this) === JSON.stringify(tree);
210229
}
@@ -233,7 +252,8 @@ if (import.meta.main) {
233252
tree.insert(170);
234253
tree.insert(15);
235254
tree.insert(1);
236-
console.log('Tree: ', JSON.stringify(BinarySearchTree.traverse(tree.getRoot())));
255+
console.log(tree.breadthFirstSearch());
256+
// console.log('Tree: ', JSON.stringify(BinarySearchTree.traverse(tree.getRoot())));
237257
tree.remove(20);
238258
printNode(tree, 4);
239259
printNode(tree, 17);
@@ -243,14 +263,21 @@ if (import.meta.main) {
243263
tree.invertTree();
244264
console.log('Inverse Tree: ', JSON.stringify(BinarySearchTree.traverse(tree.getRoot())));
245265

266+
console.log(tree.breadthFirstSearch());
267+
246268
// RUN: deno run Data-Structures/Trees/BinarySearchTree.ts
247269
}
248270

249271
// --------------------------- Terminal Output: ---------------------------
272+
// [
273+
// 9, 4, 20, 1,
274+
// 6, 15, 170
275+
// ]
250276
// Tree: {"value":9,"left":{"value":4,"left":{"value":1,"left":null,"right":null},"right":{"value":6,"left":null,"right":null}},"right":{"value":20,"left":{"value":15,"left":null,"right":null},"right":{"value":170,"left":null,"right":null}}}
251277
// Find 4: {"value":4,"left":{"value":1,"left":null,"right":null},"right":{"value":6,"left":null,"right":null}}
252278
// Find 17: Node not found.
253279
// Find 40: Node not found.
254280
// Find 170: {"value":170,"left":{"value":15,"left":null,"right":null},"right":null}
255281
// Original Tree: {"value":9,"left":{"value":4,"left":{"value":1,"left":null,"right":null},"right":{"value":6,"left":null,"right":null}},"right":{"value":170,"left":{"value":15,"left":null,"right":null},"right":null}}
256-
// Inverse Tree: {"value":9,"left":{"value":170,"left":null,"right":{"value":15,"left":null,"right":null}},"right":{"value":4,"left":{"value":6,"left":null,"right":null},"right":{"value":1,"left":null,"right":null}}}
282+
// Inverse Tree: {"value":9,"left":{"value":170,"left":null,"right":{"value":15,"left":null,"right":null}},"right":{"value":4,"left":{"value":6,"left":null,"right":null},"right":{"value":1,"left":null,"right":null}}}
283+
// [ 9, 170, 4, 15, 6, 1 ]

Data-Structures/Trees/BinaryTreeNode.ts

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,4 +32,14 @@ export default class BinaryTreeNode {
3232
public getRight(): BinaryTreeNode | any {
3333
return this.right;
3434
}
35+
36+
public hasLeft(): boolean {
37+
if (!!this.left) return true;
38+
return false;
39+
}
40+
41+
public hasRight(): boolean {
42+
if (!!this.right) return true;
43+
return false;
44+
}
3545
}

0 commit comments

Comments
 (0)