├── Data Structures ├── Stack.js ├── Queue.js ├── Trie.js ├── DoublyLinkedList.js ├── HashTable.js ├── MaxHeap.js ├── SinglyLinkedList.js └── BinaryTree.js ├── README.md └── Sorting ├── QuickSort.js └── MergeSort.js /Data Structures/Stack.js: -------------------------------------------------------------------------------- 1 | (function() { 2 | 3 | var Stack = function() { 4 | this.top = -1; 5 | this._stack = []; 6 | }; 7 | 8 | Stack.prototype.push = function(node) { 9 | this.top++; 10 | this._stack[this.top] = node; 11 | }; 12 | 13 | Stack.prototype.pop = function() { 14 | this._stack.splice(this.top, 1); 15 | this.top--; 16 | }; 17 | 18 | var stack = new Stack(); 19 | stack.push(1); 20 | stack.push(2); 21 | stack.push(3); 22 | stack.pop(); 23 | 24 | // 1, 2 25 | console.log(stack); 26 | 27 | }()); -------------------------------------------------------------------------------- /Data Structures/Queue.js: -------------------------------------------------------------------------------- 1 | (function() { 2 | 3 | var Queue = function() { 4 | this.tail = -1; 5 | this._queue = []; 6 | }; 7 | 8 | Queue.prototype.enqueue = function(node) { 9 | this.tail++; 10 | this._queue[this.tail] = node; 11 | }; 12 | 13 | Queue.prototype.dequeue = function() { 14 | var removed = this._queue.shift(); 15 | this.tail--; 16 | return removed; 17 | }; 18 | 19 | Queue.prototype.size = function() { 20 | return this.tail + 1; 21 | }; 22 | 23 | Queue.prototype.isEmpty = function() { 24 | return (this.size() === 0); 25 | }; 26 | 27 | var queue = new Queue(); 28 | queue.enqueue(1); 29 | queue.enqueue(2); 30 | queue.enqueue(3); 31 | queue.dequeue(); 32 | 33 | // 2, 3 34 | console.log(queue); 35 | 36 | 37 | }()); 38 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Computer Science in JavaScript 2 | 3 | Contains the basic fundamental data structures and algorithms a front end engineer should know, written all in JavaScript. 4 | 5 | Front end engineers need to know a mixture of technologies and methodologies from JavaScript, CSS, HTML to design patterns, MVC/MVVM, browser performance and responsive design to name but a few concepts. 6 | 7 | However, Computer Science, and in particular data structures and algorithms are often ignored. While you may not use these on a day to day basis, user interfaces are becoming more complex and feature rich. 8 | 9 | Every front end engineer should be able to grasp the fundamentals of the following: 10 | 11 | ## Data Structures 12 | 13 | * Binary Trees 14 | * Doubly Linked Lists 15 | * HashTables 16 | * MaxHeaps 17 | * Queues 18 | * Singly Linked Lists 19 | * Stacks 20 | * Tries 21 | 22 | ## Sorting Algorithms 23 | 24 | * Binary Search 25 | * Merge Sort 26 | * Quick Sort 27 | -------------------------------------------------------------------------------- /Sorting/QuickSort.js: -------------------------------------------------------------------------------- 1 | (function() { 2 | 3 | var QuickSort = function(inputArr) { 4 | 5 | var len = inputArr.length, 6 | left = [], 7 | right = [], 8 | pivot; 9 | 10 | if (len === 0) { 11 | return inputArr; 12 | } 13 | 14 | pivot = inputArr[0]; 15 | 16 | // partition values into upper and lower 17 | // start at second element, since we are using first element as the pivot 18 | for (var i = 1; i < len; i++) { 19 | 20 | if (inputArr[i] <= pivot) { 21 | left.push(inputArr[i]); 22 | } 23 | else { 24 | right.push(inputArr[i]); 25 | } 26 | 27 | } 28 | 29 | left = QuickSort(left); 30 | right = QuickSort(right); 31 | 32 | return left.concat(pivot, right); 33 | 34 | }; 35 | 36 | var myArray = [2, 4, 1, 6, 8, 5, 9, 3, 4]; 37 | 38 | // [1, 2, 3, 4, 4, 5, 6, 8, 9] 39 | QuickSort(myArray); 40 | 41 | }()); 42 | -------------------------------------------------------------------------------- /Data Structures/Trie.js: -------------------------------------------------------------------------------- 1 | (function() { 2 | 3 | var Trie = function() { 4 | this.root = {}; 5 | }; 6 | 7 | Trie.prototype.add = function(word) { 8 | 9 | if (word) { 10 | 11 | var current = this.root; 12 | 13 | for (var i = 0, len = word.length; i < len; i++) { 14 | 15 | // letter in the trie dosen't exist, add it 16 | if (word[i] in current === false) { 17 | current[word[i]] = { 18 | 'end_of_key': false 19 | }; 20 | } 21 | 22 | // move pointer forward 23 | current = current[word[i]]; 24 | 25 | } 26 | 27 | current.end_of_key = true; 28 | 29 | } 30 | 31 | }; 32 | 33 | Trie.prototype.isMember = function(word) { 34 | 35 | if (word) { 36 | 37 | var current = this.root; 38 | 39 | // walkthrough to the last letter in for the searched word 40 | var i = 0; 41 | while (current && i < word.length) { 42 | current = current[word[i]]; 43 | i += 1; 44 | } 45 | 46 | // last letter in the word exists in the trie, and is marked as an end of word 47 | if (current && current.end_of_key === true) { 48 | return true; 49 | } 50 | 51 | } 52 | 53 | return false; 54 | 55 | }; 56 | 57 | Trie.prototype.remove = function(word) { 58 | 59 | for (var i = 0, current = this.root, len = word.length; i < len; i++) { 60 | current = current[word[i]]; 61 | } 62 | 63 | // end of word 64 | if (current && current.end_of_key === true) { 65 | current.end_of_key = false; 66 | } 67 | 68 | }; 69 | 70 | var trie = new Trie(); 71 | trie.add('Hello'); 72 | trie.add('Help'); 73 | trie.add('Helper'); 74 | trie.add('Helped'); 75 | 76 | trie.isMember('Hexagon');// false 77 | trie.isMember('Helpe'); // false 78 | trie.isMember('Helper'); // true 79 | trie.isMember('Help'); // true 80 | 81 | trie.remove('Help'); 82 | 83 | trie.isMember('Help'); // false 84 | 85 | }()); 86 | -------------------------------------------------------------------------------- /Sorting/MergeSort.js: -------------------------------------------------------------------------------- 1 | (function() { 2 | 3 | var Merge = function(left, right) { 4 | 5 | var l = 0, 6 | r = 0, 7 | k = 0, 8 | l_len = left.length, 9 | r_len = right.length, 10 | result = []; 11 | 12 | // go through both arrays, comparing each element against the element in the adjacent array 13 | while (l < l_len && r < r_len) { 14 | 15 | if (left[l] < right[r]) { 16 | result[k] = left[l]; 17 | l++; 18 | } 19 | else { 20 | result[k] = right[r]; 21 | r++; 22 | } 23 | 24 | // move the pointer of the result array forward 25 | k++; 26 | 27 | } 28 | 29 | // if one of the arrays is larger than the other, we may have some leftovers 30 | while (l < l_len) { 31 | result[k] = left[l]; 32 | l++; 33 | k++; 34 | } 35 | while (r < r_len) { 36 | result[k] = right[r]; 37 | r++; 38 | k++; 39 | } 40 | 41 | return result; 42 | 43 | }, 44 | MergeSort = function(inputArr) { 45 | 46 | var len = inputArr.length, 47 | left = [], 48 | right = [], 49 | mid; 50 | 51 | // less than 2 elements means we can't merge / compare anything 52 | if (len < 2) { 53 | return inputArr; 54 | } 55 | 56 | // find the middle, rounding up for odd no of elems 57 | mid = Math.floor(len / 2); 58 | 59 | // split left and right into sub-arrays 60 | left = inputArr.slice(0, mid); 61 | right = inputArr.slice(mid); 62 | 63 | // keep dividing the sub-arrays 64 | left = MergeSort(left); 65 | right = MergeSort(right); 66 | 67 | // conquer the sub-arrays by sorting and merging them 68 | return Merge(left, right); 69 | 70 | }; 71 | 72 | var myArray = [2, 4, 1, 6, 8, 5, 9, 3, 4]; 73 | 74 | // [1, 2, 3, 4, 4, 5, 6, 8, 9] 75 | MergeSort(myArray); 76 | 77 | }()); 78 | -------------------------------------------------------------------------------- /Data Structures/DoublyLinkedList.js: -------------------------------------------------------------------------------- 1 | (function() { 2 | 3 | var DoublyLinkedList = function() { 4 | this.head = null; 5 | this.tail = null; 6 | }, 7 | LinkedNode = function(data) { 8 | this.data = data; 9 | this.next = null; 10 | this.prev = null; 11 | }; 12 | 13 | DoublyLinkedList.prototype.insert = function(data) { 14 | 15 | var node = new LinkedNode(data); 16 | 17 | if (!this.head) { 18 | this.head = this.tail = node; 19 | } 20 | else { 21 | this.tail.next = node; 22 | node.prev = this.tail; 23 | this.tail = node; 24 | } 25 | 26 | return node; 27 | 28 | }; 29 | 30 | DoublyLinkedList.prototype.remove = function(data) { 31 | 32 | if (!this.head.next) { 33 | this.head = this.tail = null; 34 | } 35 | else { 36 | 37 | var curr = this.head; 38 | 39 | while (curr) { 40 | 41 | if (curr.data === data) { 42 | 43 | curr.prev.next = curr.next; 44 | if(cur === this.tail) this.tail = cur.prev; 45 | else cur.next.prev = cur.prev; 46 | curr = null; 47 | 48 | } 49 | else { 50 | curr = curr.next; 51 | } 52 | 53 | } 54 | 55 | } 56 | 57 | }; 58 | 59 | DoublyLinkedList.prototype.find = function(data) { 60 | 61 | var curr = this.head; 62 | 63 | while (curr) { 64 | if (curr.data === data) { 65 | return curr; 66 | } 67 | curr = curr.next; 68 | } 69 | 70 | }; 71 | 72 | DoublyLinkedList.prototype.print = function() { 73 | 74 | var curr = this.head; 75 | 76 | while (curr) { 77 | console.log(curr); 78 | curr = curr.next; 79 | } 80 | 81 | }; 82 | 83 | var myList = new DoublyLinkedList(); 84 | 85 | myList.insert('a'); 86 | myList.insert('b'); 87 | myList.insert('c'); 88 | myList.insert('d'); 89 | myList.insert('e'); 90 | 91 | myList.remove('b'); 92 | myList.remove('e'); 93 | myList.find('a'); 94 | myList.print(); 95 | 96 | }()); 97 | -------------------------------------------------------------------------------- /Data Structures/HashTable.js: -------------------------------------------------------------------------------- 1 | (function() { 2 | 3 | var HashTable = function() { 4 | this.items = []; 5 | this.items.length = 100; 6 | }, 7 | HashStruc = function(val) { 8 | this.val = val; 9 | this.next = null; 10 | }; 11 | 12 | HashTable.prototype.hash = function(val) { 13 | 14 | var hashIndex = 0; 15 | 16 | for (var i = 0, len = val.length; i < len; i++) { 17 | hashIndex = i + (hashIndex << 5) - hashIndex; 18 | } 19 | 20 | return hashIndex % this.items.length; 21 | 22 | }; 23 | 24 | HashTable.prototype.add = function(val) { 25 | 26 | // already exists in the table 27 | if (this.lookup(val) !== null) { 28 | return; 29 | } 30 | // create elements as linked list 31 | else { 32 | 33 | var node = new HashStruc(val), 34 | hash = this.hash(val); 35 | 36 | node.val = val; 37 | node.next = this.items[hash]; 38 | this.items[hash] = node; 39 | 40 | } 41 | 42 | }; 43 | 44 | HashTable.prototype.remove = function(val) { 45 | 46 | var node = this.lookup(val); 47 | 48 | if (node) { 49 | 50 | var hash = this.hash(val), 51 | list = this.items[hash], 52 | prev = {}; 53 | 54 | while(list) { 55 | // node to delete is first in list 56 | if (this.items[hash].val === val) { 57 | this.items[hash] = this.items[hash].next; 58 | return; 59 | } 60 | else if (list.val === val) { 61 | prev.next = list.next; 62 | list = null; 63 | return; 64 | } 65 | prev = list; 66 | list = list.next; 67 | } 68 | 69 | } 70 | 71 | }; 72 | 73 | HashTable.prototype.lookup = function(val) { 74 | 75 | var hash = this.hash(val), 76 | node = this.items[hash]; 77 | 78 | if (node) { 79 | 80 | while (node) { 81 | // found the node 82 | if (node.val === val) { 83 | return node; 84 | } 85 | node = node.next; 86 | } 87 | 88 | } 89 | 90 | return null; 91 | 92 | }; 93 | 94 | table = new HashTable(); 95 | 96 | // insert single node 97 | table.add('dddddddddd'); 98 | 99 | // create a collision based on the hash function 100 | table.add('aaa'); 101 | table.add('bbb'); 102 | table.add('ccc'); 103 | 104 | table.remove('bbb'); 105 | 106 | }()); 107 | -------------------------------------------------------------------------------- /Data Structures/MaxHeap.js: -------------------------------------------------------------------------------- 1 | (function() { 2 | 3 | var MaxHeap = function() { 4 | this.items = []; 5 | this.size = -1; 6 | }; 7 | 8 | MaxHeap.prototype.insert = function(val) { 9 | 10 | var pos = ++this.size, 11 | parentIndex = this.findParentIndex(pos); 12 | 13 | // new elements go to last position 14 | this.items[pos] = val; 15 | 16 | if (pos > 0) { 17 | 18 | // bubble up new value 19 | while (this.items[pos] > this.items[parentIndex]) { 20 | 21 | // update values 22 | this.items[pos] = this.items[parentIndex]; 23 | this.items[parentIndex] = val; 24 | 25 | // move pointers 26 | pos = parentIndex; 27 | parentIndex = this.findParentIndex(pos); 28 | 29 | } 30 | 31 | } 32 | 33 | return pos; 34 | 35 | }; 36 | 37 | MaxHeap.prototype.deleteMax = function() { 38 | 39 | // remove current root and replace with last node 40 | this.items[0] = this.items[this.size]; 41 | this.items.pop(); 42 | this.size--; 43 | 44 | var current = this.items[0], 45 | currPos = 0, 46 | indexLeft, indexRight, indexReplace; 47 | 48 | while (current) { 49 | 50 | indexLeft = (2 * currPos) + 1; 51 | indexRight = (2 * currPos) + 2; 52 | 53 | if (this.items[indexLeft] > this.items[indexRight] && 54 | this.items[indexLeft] > current) { 55 | 56 | indexReplace = indexLeft; 57 | 58 | } 59 | else if (this.items[indexRight] > this.items[indexLeft] && 60 | this.items[indexRight] > current) { 61 | 62 | indexReplace = indexRight; 63 | 64 | } 65 | else { 66 | break; 67 | } 68 | 69 | // swap the current node with the greater child node 70 | this.items[currPos] = this.items[indexReplace]; 71 | this.items[indexReplace] = current; 72 | currPos = indexReplace; 73 | current = this.items[currPos]; 74 | 75 | } 76 | 77 | }; 78 | 79 | MaxHeap.prototype.findParentIndex = function(index) { 80 | return Math.floor((index - 1) / 2); 81 | }; 82 | 83 | var heap = new MaxHeap(); 84 | 85 | // [20, 13, 9, 8, 5, 3, 7, 6, 2, 1, 19] 86 | heap.insert(20); 87 | heap.insert(13); 88 | heap.insert(9); 89 | heap.insert(8); 90 | heap.insert(5); 91 | heap.insert(3); 92 | heap.insert(7); 93 | heap.insert(6); 94 | heap.insert(2); 95 | heap.insert(1); 96 | 97 | // [20, 19, 9, 8, 13, 3, 7, 6, 2, 1, 5] 98 | heap.insert(19); 99 | 100 | // [25, 19, 20, 8, 13, 9, 7, 6, 2, 1, 5, 3] 101 | heap.insert(25); 102 | 103 | // [20, 19, 9, 8, 13, 3, 7, 6, 2, 1, 5] 104 | heap.deleteMax(); 105 | 106 | // [19, 13, 9, 8, 5, 3, 7, 6, 2, 1] 107 | heap.deleteMax(); 108 | 109 | }()); 110 | -------------------------------------------------------------------------------- /Data Structures/SinglyLinkedList.js: -------------------------------------------------------------------------------- 1 | (function() { 2 | 3 | var LinkedList = function() { 4 | this.head = null; 5 | }, 6 | LinkedNode = function(data) { 7 | this.data = data; 8 | this.next = null; 9 | }; 10 | 11 | LinkedList.prototype.insert = function(data) { 12 | 13 | var node = new LinkedNode(data), 14 | curr = this.head; 15 | 16 | if (!curr) { 17 | this.head = node; 18 | } 19 | else { 20 | 21 | while (curr.next) { 22 | curr = curr.next; 23 | } 24 | 25 | curr.next = node; 26 | } 27 | 28 | return node; 29 | 30 | }; 31 | 32 | LinkedList.prototype.remove = function(data) { 33 | 34 | if (this.head.data === data) { 35 | this.head = this.head.next || null; 36 | } 37 | else { 38 | 39 | var curr = this.head, 40 | prev = null; 41 | 42 | while (curr) { 43 | 44 | if (curr.data === data) { 45 | prev.next = curr.next; 46 | curr = null; 47 | } 48 | else { 49 | prev = curr; 50 | curr = curr.next; 51 | } 52 | 53 | } 54 | 55 | } 56 | 57 | }; 58 | 59 | LinkedList.prototype.find = function(data) { 60 | 61 | var curr = this.head; 62 | 63 | while (curr) { 64 | if (curr.data === data) { 65 | return curr; 66 | } 67 | curr = curr.next; 68 | } 69 | 70 | }; 71 | 72 | LinkedList.prototype.print = function() { 73 | 74 | var curr = this.head; 75 | 76 | while (curr) { 77 | console.log(curr); 78 | curr = curr.next; 79 | } 80 | 81 | }; 82 | 83 | LinkedList.prototype.nToLast = function(k) { 84 | 85 | var p1 = this.head, 86 | p2 = this.head; 87 | 88 | // move p2 ahead of p1 by k places 89 | for (var i = 0; i < k - 1; i++) { 90 | p2 = p2.next; 91 | } 92 | 93 | // keep moving p1 and p2, when p2 hits the end then p1 is k 94 | while (p2.next) { 95 | p1 = p1.next; 96 | p2 = p2.next; 97 | } 98 | 99 | return p1; 100 | 101 | }; 102 | 103 | LinkedList.prototype.reverse = function() { 104 | 105 | var curr = this.head, 106 | prev = null, 107 | next = null; 108 | 109 | while (curr) { 110 | 111 | // save the ref to next node to move forward later 112 | next = curr.next; 113 | 114 | // break current link, and set it to node before 115 | curr.next = prev; 116 | 117 | // keep traversing the list by moving pointers forward 118 | prev = curr; 119 | curr = next; 120 | 121 | } 122 | 123 | this.head = prev; 124 | 125 | }; 126 | 127 | LinkedList.prototype.deleteAtNode = function(node) { 128 | 129 | // can't delete last node in list 130 | if (!node || !node.next) { 131 | return false; 132 | } 133 | 134 | // copy data from next node to the node to be deleted 135 | node.data = node.next.data; 136 | node.next = node.next.next; 137 | 138 | return true; 139 | 140 | }; 141 | 142 | var myList = new LinkedList(); 143 | 144 | myList.insert('a'); 145 | myList.insert('b'); 146 | myList.insert('c'); 147 | myList.insert('d'); 148 | myList.insert('e'); 149 | myList.insert('f'); 150 | 151 | myList.remove('b'); 152 | myList.find('a'); 153 | 154 | // e 155 | myList.nToLast(2); 156 | 157 | myList.reverse(); 158 | 159 | // f->e->d->c->a 160 | myList.print(); 161 | 162 | }()); 163 | -------------------------------------------------------------------------------- /Data Structures/BinaryTree.js: -------------------------------------------------------------------------------- 1 | (function() { 2 | 3 | var BinaryTree = function() { 4 | this.root = null; 5 | }, 6 | BinaryNode = function(val) { 7 | this.val = val; 8 | // new nodes are leafs 9 | this.left = null; 10 | this.right = null; 11 | }; 12 | 13 | BinaryTree.prototype.insert = function(val) { 14 | 15 | var node = new BinaryNode(val); 16 | 17 | if (this.root === null) { 18 | this.root = node; 19 | } 20 | else { 21 | this.insertNode(node, this.root); 22 | } 23 | 24 | }; 25 | 26 | BinaryTree.prototype.locate = function(find) { 27 | 28 | if (this.root.val === find) { 29 | return this.root; 30 | } 31 | else { 32 | return this.locateNode(find, this.root); 33 | } 34 | 35 | }; 36 | 37 | BinaryTree.prototype.locateNode = function(find, subtree) { 38 | 39 | if (!subtree) { 40 | return null; 41 | } 42 | else { 43 | // found the matching node 44 | if (find === subtree.val) { 45 | return subtree; 46 | } 47 | else if (find < subtree.val) { 48 | return this.locateNode(find, subtree.left); 49 | } 50 | else if (find > subtree.val) { 51 | return this.locateNode(find, subtree.right); 52 | } 53 | } 54 | 55 | }; 56 | 57 | // pre-order insert 58 | BinaryTree.prototype.insertNode = function(node, subtree) { 59 | 60 | // no value in current tree, insert it here 61 | if (!subtree) { 62 | subtree = node; 63 | } 64 | else if (node.val < subtree.val) { 65 | subtree.left = this.insertNode(node, subtree.left); 66 | } 67 | else if (node.val > subtree.val) { 68 | subtree.right = this.insertNode(node, subtree.right); 69 | } 70 | 71 | return subtree; 72 | 73 | }; 74 | 75 | BinaryTree.prototype.printPreOrder = function(subtree) { 76 | 77 | if (!subtree) { 78 | return; 79 | } 80 | 81 | console.log(subtree.val); 82 | this.printPreOrder(subtree.left); 83 | this.printPreOrder(subtree.right); 84 | 85 | }; 86 | 87 | BinaryTree.prototype.printInOrder = function(subtree) { 88 | 89 | if (!subtree) { 90 | return; 91 | } 92 | 93 | this.printInOrder(subtree.left); 94 | console.log(subtree.val); 95 | this.printInOrder(subtree.right); 96 | 97 | }; 98 | 99 | BinaryTree.prototype.printPostOrder = function(subtree) { 100 | 101 | if (!subtree) { 102 | return; 103 | } 104 | 105 | this.printPostOrder(subtree.left); 106 | this.printPostOrder(subtree.right); 107 | console.log(subtree.val); 108 | 109 | }; 110 | 111 | BinaryTree.prototype.remove = function(val, subtree) { 112 | 113 | // find the node to remove and its parent 114 | 115 | var node = null, 116 | parent = null, 117 | dir = ''; 118 | 119 | subtree = subtree || this.root; 120 | 121 | while (subtree) { 122 | 123 | // found node 124 | if (subtree.val === val) { 125 | node = subtree; 126 | break; 127 | } 128 | else if (val < subtree.val) { 129 | parent = subtree; 130 | subtree = subtree.left; 131 | dir = 'left'; 132 | } 133 | else if (val > subtree.val) { 134 | parent = subtree; 135 | subtree = subtree.right; 136 | dir = 'right'; 137 | } 138 | 139 | } 140 | 141 | if (!node) { 142 | return null; 143 | } 144 | 145 | // case 1 - two children 146 | if (node.left && node.right) { 147 | 148 | // find the highest node on the left subtree 149 | // copy it + its parent 150 | 151 | var replacement = node.left, 152 | replacementParent = node; 153 | 154 | while (replacement.right) { 155 | replacementParent = replacement; 156 | replacement = replacement.right; 157 | } 158 | 159 | // copy children from node to be deleted 160 | replacement.left = node.left; 161 | replacement.right = node.right; 162 | 163 | // remove the highest left node 164 | replacementParent.right = null; 165 | 166 | // update parent to point to highest left node 167 | if (dir) { 168 | parent[dir] = replacement; 169 | } 170 | // delete root node 171 | else { 172 | this.root = replacement; 173 | } 174 | 175 | } 176 | // case 2 - no children 177 | else if (!node.left && !node.right) { 178 | parent[dir] = null; 179 | } 180 | // case 3 - one child 181 | else { 182 | parent[dir] = node.left ? node.left : node.right; 183 | } 184 | 185 | // cleanup deleted node 186 | node = null; 187 | 188 | }; 189 | 190 | BinaryTree.prototype.breadthFirstSearch = function(val) { 191 | 192 | var queue = [this.root], 193 | current = null; 194 | 195 | while (queue[0]) { 196 | 197 | current = queue.shift(); 198 | 199 | if (val === current.val) { 200 | return current; 201 | } 202 | else { 203 | 204 | if (current.left) { 205 | queue.push(current.left); 206 | } 207 | if (current.right) { 208 | queue.push(current.right); 209 | } 210 | 211 | } 212 | 213 | } 214 | 215 | return null; 216 | 217 | }; 218 | 219 | var tree = new BinaryTree(); 220 | tree.insert(20); 221 | tree.insert(10); 222 | tree.insert(15); 223 | tree.insert(16); 224 | tree.insert(5); 225 | tree.insert(8); 226 | tree.insert(25); 227 | 228 | tree.locate(15); 229 | tree.remove(20); 230 | tree.breadthFirstSearch(15); 231 | 232 | tree.printPreOrder(tree.root); 233 | 234 | }()); 235 | --------------------------------------------------------------------------------