├── AVLTree └── AVLTree.js ├── BinarySearch ├── README.md ├── bs.js ├── bs.py └── bs.r ├── BinaryTree └── binaryTree.js ├── HashTable └── hashtable.js ├── LinkedList └── singlyLinkedList.js ├── Queue ├── arrayQueue.js ├── linkedlistQueue.js └── priorityQueue.js ├── QuickSort ├── README.md └── qs.js ├── README.md ├── SelectionSort ├── README.md └── ss.js ├── SetAlgorithms ├── intersection.js ├── setDifference.js ├── symmetricDifference.js └── union.js ├── SortingAlgorithm ├── bubblesort.js ├── insertionsort.js └── mergesort.js └── Stack ├── arrayStack.js ├── linkedlistStack.js └── postfixCalc.js /AVLTree/AVLTree.js: -------------------------------------------------------------------------------- 1 | const BinaryTree = require('../BinaryTree/binaryTree'); 2 | 3 | class AVLTree extends BinaryTree{ 4 | 5 | // Node Height 6 | leftHeight(node){ 7 | return this.maxChildHeight(node); 8 | } 9 | rightHeight(node) { 10 | return this.maxChildHeight(node); 11 | } 12 | maxChildHeight(node) { 13 | if (node != null) { 14 | return 1 + Math.max(this.maxChildHeight(node.left), this.maxChildHeight(node.right)) 15 | } 16 | return 0; 17 | } 18 | 19 | // Balance factor 20 | balanceFactor(right, left) { 21 | return ( 22 | this.rightHeight(right) - this.leftHeight(left) 23 | ); 24 | } 25 | 26 | // heavy or balanced 27 | checkState(right, left) { 28 | const bf = this.balanceFactor(right, left); 29 | if (bf > 1) { 30 | return "rightHeavy"; 31 | } 32 | if (bf < 0) { 33 | return "leftHeavy"; 34 | } 35 | else { 36 | return "balanced"; 37 | } 38 | } 39 | 40 | // choosing right rotation 41 | 42 | // insertion 43 | insert(value) { 44 | super.add(value); 45 | } 46 | 47 | leftRotation() { 48 | 49 | } 50 | rightRotation() { 51 | 52 | } 53 | rightLeftRotation() { 54 | 55 | } 56 | leftRightRotation() { 57 | 58 | } 59 | } 60 | 61 | const tree = new AVLTree() 62 | tree.insert(1) 63 | tree.insert(2) 64 | tree.insert(3); 65 | tree.insert(4); 66 | console.log(tree.checkState(tree.root.right, tree.root.left)); 67 | // console.log(tree) 68 | -------------------------------------------------------------------------------- /BinarySearch/README.md: -------------------------------------------------------------------------------- 1 | # Binary Search 2 | 3 | A search algorithm used with a sorted list of items by eliminating half of the elements every time. 4 | 5 | - Input - Sorted list of elements , target element 6 | 7 | - Output - position of found element or null if not found 8 | 9 | ## Algorithm 10 | 11 | 1. Store low and high index 12 | 2. Repeat while low <= high 13 | 1. Calculate mid index, (low+high)/2 14 | 2. if elements[mid] equals target, return mid 15 | 3. if elements[mid] is higher than target, update high index (mid - 1) 16 | 4. else, update low index (mid + 1) 17 | 3. If loop ends without finding target, return null 18 | 19 | Time Complexity: O(log n) 20 | -------------------------------------------------------------------------------- /BinarySearch/bs.js: -------------------------------------------------------------------------------- 1 | function binarySearch(arr, target) { 2 | let low = 0; 3 | let high = arr.length - 1; 4 | 5 | while (low <= high) { 6 | let mid = Math.floor((low + high) / 2); 7 | let guess = arr[mid]; 8 | if (guess === target) { 9 | return mid; 10 | } else if (guess > target) { 11 | high = mid - 1; 12 | } else { 13 | low = mid + 1; 14 | } 15 | } 16 | return -1; 17 | } 18 | 19 | // example 20 | const arr = [1, 2, 3, 4, 5, 6, 7, 8]; 21 | const target = 5; 22 | console.log(binarySearch(arr, target)); // 4 -------------------------------------------------------------------------------- /BinarySearch/bs.py: -------------------------------------------------------------------------------- 1 | def binary_search(arr, target): 2 | low = 0 3 | high = len(arr)-1 4 | while low <= high: 5 | mid = (low+high)//2 6 | guess = arr[mid] 7 | if guess == target: 8 | return mid 9 | if guess > target: 10 | high = mid - 1 11 | else: 12 | low = mid + 1 13 | return None 14 | 15 | # example 16 | arr = [1, 2, 3, 4, 5, 6, 7, 8]; 17 | target = 5 18 | print(binary_search(arr, target)) # 4 19 | -------------------------------------------------------------------------------- /BinarySearch/bs.r: -------------------------------------------------------------------------------- 1 | binary_search <- function(arr, target) { 2 | low <- 1 3 | high <- length(arr) 4 | while (low <= high) { 5 | mid <- low + (high - low) %/% 2 6 | guess <- arr[mid] 7 | if (guess == target) { 8 | return(mid) 9 | } 10 | if (guess > target) { 11 | high <- mid - 1 12 | } else { 13 | low <- mid + 1 14 | } 15 | } 16 | return - 1 17 | } 18 | 19 | # example 20 | arr <- c(1, 2, 3, 4, 5, 6, 7, 8) 21 | target <- 5 22 | print(binary_search(arr, target)) # 5 23 | -------------------------------------------------------------------------------- /BinaryTree/binaryTree.js: -------------------------------------------------------------------------------- 1 | 2 | 3 | class Node{ 4 | constructor(data) { 5 | this.data = data; 6 | this.left = null; 7 | this.right = null; 8 | } 9 | } 10 | 11 | class BinaryTree{ 12 | constructor() { 13 | this.root = null; 14 | } 15 | 16 | add(data) { 17 | const newNode = new Node(data); 18 | if (this.root === null) { 19 | this.root = newNode; 20 | } 21 | else { 22 | this._addTo(this.root, newNode); 23 | } 24 | } 25 | 26 | _addTo(currentNode, newNode) { 27 | if (newNode.data < currentNode.data) { 28 | if (currentNode.left === null) { 29 | //if new node is less than the current node 30 | //add to left 31 | currentNode.left = newNode; 32 | } else { 33 | this._addTo(currentNode.left, newNode); 34 | } 35 | } else { 36 | //if new node is greater than/ equal to the current node 37 | //add to right 38 | if (currentNode.right === null) { 39 | currentNode.right = newNode; 40 | } else { 41 | this._addTo(currentNode.right, newNode); 42 | } 43 | 44 | } 45 | } 46 | 47 | //try find data in tree 48 | contains(data) { 49 | let current = this.root; 50 | let parent = null 51 | 52 | //while we don't have a match 53 | while (current !== null) { 54 | if (data < current.data) { 55 | //if value is less than current, go left 56 | parent = current; 57 | current = current.left; 58 | } else if (data > current.data) { 59 | //if value is greater than current, go right 60 | parent = current; 61 | current = current.right; 62 | } else { 63 | //we have a match 64 | break; 65 | } 66 | } 67 | return[ current, parent ]; 68 | } 69 | 70 | find(data) { 71 | return this.contains(data)[0]; 72 | } 73 | 74 | remove(data) { 75 | let parent = this.contains(data)[1]; 76 | let current = this.find(data); 77 | 78 | if (current === null) { 79 | return false; 80 | } 81 | 82 | //CASE 1 83 | //removing node with no right child 84 | //its left child replaces the removed node 85 | if (current.right === null) { 86 | if (parent === null) { 87 | //if we are removing root node 88 | this.root = current.left; 89 | } else { 90 | if (parent.data > current.data) { 91 | //make current left child, left child of parent 92 | //rare case 93 | parent.left = current.left; 94 | } else if (parent.data < current.data) { 95 | //make current left child, right child of parent 96 | parent.right = current.left; 97 | } 98 | } 99 | } 100 | 101 | //CASE 2 102 | //removing node whose right child has no left child 103 | //right child replaces the removed node 104 | else if (current.right.left === null) { 105 | //move removed node left child to the left of removedd's right 106 | current.right.left = current.left; 107 | if (parent === null) { 108 | this.root = current.right; 109 | } else { 110 | if (parent.data > current.data) { 111 | //make current right child a left child of parent 112 | parent.left = current.right; 113 | } else if (parent.data < current.data) { 114 | //make current right child a right child of parent 115 | parent.right = current.right; 116 | } 117 | } 118 | 119 | } 120 | 121 | //CASE 3 122 | //if removed node's right child has a left child 123 | //replace removed with its right child's left most node 124 | else { 125 | //find right leftmost child 126 | let leftMost = current.right.left; 127 | let leftMostParent = current.right; 128 | while (leftMost.left != null) { 129 | //move to the left most node of the right child 130 | leftMostParent = leftMost; 131 | leftMost = leftMost.left; 132 | } 133 | //the parent's left subtree becomes the leftmost's right subtree 134 | leftMostParent.left = leftMost.right; 135 | //assign leftmost's left n right to current's left n right 136 | leftMost.left = current.left; 137 | leftMost.right = current.right; 138 | if (parent === null) { 139 | this.root = leftMost; 140 | } 141 | else { 142 | if (parent.data > current.data) { 143 | //make leftmost the parent's left child 144 | parent.left = leftMost; 145 | } else if (parent.data < current.data) { 146 | //make leftmost the parent's right child 147 | parent.right = leftMost 148 | } 149 | } 150 | } 151 | return true; 152 | 153 | } 154 | 155 | //TREE TRAVERSAL 156 | preorder(current) { 157 | if (current === null) { 158 | return; 159 | } 160 | console.log(current.data); 161 | this.preorder(current.left); 162 | this.preorder(current.right); 163 | } 164 | 165 | postorder(current) { 166 | if (current === null) { 167 | return; 168 | } 169 | this.postorder(current.left); 170 | this.postorder(current.right); 171 | console.log(current.data); 172 | } 173 | 174 | inorder(current) { 175 | if (current === null) { 176 | return; 177 | } 178 | this.inorder(current.left); 179 | console.log(current.data); 180 | this.inorder(current.right); 181 | } 182 | 183 | } 184 | 185 | // const tree = new BinaryTree(); 186 | // tree.add(4); 187 | // tree.add(2); 188 | // tree.add(1); 189 | // tree.add(3); 190 | // tree.add(6); 191 | // tree.add(5); 192 | // tree.add(7) 193 | // tree.find(6); 194 | // tree.remove(6) 195 | 196 | // tree.postorder(tree.root) // 1 3 2 5 7 6 4 197 | // tree.preorder(tree.root) // 4 2 1 3 6 5 7 198 | // tree.inorder(tree.root) // 1 2 3 4 5 6 7 199 | 200 | module.exports = BinaryTree; 201 | -------------------------------------------------------------------------------- /HashTable/hashtable.js: -------------------------------------------------------------------------------- 1 | class Node { 2 | constructor(key, data) { 3 | this.key = key; 4 | this.data = data; 5 | this.next = null; 6 | this.previous = null; 7 | } 8 | } 9 | 10 | class HashTable{ 11 | constructor() { 12 | this.buckets = []; 13 | this.maxBucketCount = 100; 14 | } 15 | 16 | hashCode(val) { 17 | let i; 18 | let hashCode = 0; 19 | let character; 20 | 21 | // If value to be hashed is already an integer, return it. 22 | if (val.length === 0 || val.length === undefined) { 23 | return val; 24 | } 25 | 26 | for (i = 0; i < val.length; i++) { 27 | character = val.charCodeAt(i); 28 | hashCode = ((hashCode << 5) - hashCode) + character; 29 | hashCode = hashCode & hashCode; 30 | } 31 | 32 | return hashCode % this.maxBucketCount; 33 | }; 34 | 35 | // add key/data pair to bucket 36 | add(key, data) { 37 | let newNode = new Node(key, data); 38 | let hashCode = this.hashCode(key); // get hashcode of key 39 | 40 | // if no element exists at hashcode of key, add to table 41 | if (this.buckets[hashCode] === undefined) { 42 | this.buckets[hashCode] = newNode; 43 | return; 44 | } 45 | 46 | // if an element exists at hashcode of key, but keys are same 47 | // update key with given data 48 | if (this.buckets[hashCode].key === key) { 49 | this.buckets[hashCode].data = data; 50 | return; 51 | } 52 | 53 | // if an element exists at hashcode of key, but keys are different 54 | // collision has occured 55 | // store in linked list 56 | let current = this.buckets[hashCode]; 57 | while (current.next !== null) { 58 | current = current.next; 59 | } 60 | current.next = newNode; 61 | newNode.previous = current 62 | } 63 | 64 | remove(key) { 65 | let hashCode = this.hashCode(key); // get hashcode of key 66 | let first = this.buckets[hashCode] //select key/data pair at index 67 | 68 | if (first !== undefined) { 69 | // if it exists and no has linked list at index 70 | // (A) 71 | if (first.next === null) { 72 | this.buckets[hashCode] = undefined; // remove item 73 | return; 74 | } else { 75 | while (first !== null && first.next !== null && first.key !== key) { 76 | first = first.next; 77 | } 78 | // if removed is first node in list 79 | // (A) - B - C - D 80 | if (first.previous === null && first.next !==null) { 81 | while (first.next !== null) { 82 | first.key = first.next.key; 83 | first.data = first.next.data; 84 | first.next.previous.data = first.data 85 | first.next.previous.key = first.key 86 | first = first.next; 87 | } 88 | } 89 | 90 | // if removed is last node in list 91 | // A - B - (C) 92 | if (first.previous !== null && first.next === null) { 93 | first.previous.next = null 94 | first = null 95 | return; 96 | } 97 | 98 | // if removed is middle node 99 | // A - (B) - C 100 | if (first.previous !== null && first.next !== null) { 101 | first.previous.next = first.next; 102 | first.next.previous = first.previous; 103 | first = null; 104 | return; 105 | } 106 | return; 107 | } 108 | } 109 | return undefined; 110 | } 111 | 112 | find(key) { 113 | let hashCode = this.hashCode(key); 114 | let current = this.buckets[hashCode]; 115 | if (current !== undefined) { 116 | if (current.next === null && current.key === key) { 117 | return current.data; 118 | } else { 119 | while (current != null && current.next != null && current.key !== key) { 120 | current = current.next; 121 | } 122 | if (current.key === key) { 123 | return current.data; 124 | } 125 | return undefined; 126 | } 127 | 128 | } 129 | return undefined; 130 | 131 | } 132 | } 133 | 134 | const hashTable = new HashTable(); 135 | 136 | hashTable.add('foo', '2') 137 | hashTable.add(2, '3') 138 | hashTable.add(2, '4') 139 | hashTable.add(2, '5') 140 | hashTable.add(2, '6') 141 | hashTable.add(2, '7') 142 | console.log(hashTable.find(2)) 143 | 144 | while (array[index] !== null) 145 | index++ 146 | array[index] = item -------------------------------------------------------------------------------- /LinkedList/singlyLinkedList.js: -------------------------------------------------------------------------------- 1 | class Node { 2 | constructor(data, next = null) { 3 | this.data = data; 4 | this.next = next; 5 | } 6 | } 7 | 8 | class LinkedList { 9 | constructor() { 10 | this.head = null; 11 | this.size = 0; 12 | } 13 | 14 | //Add to start of list 15 | insertFirst(data) { 16 | this.head = new Node(data, this.head); 17 | this.size++; 18 | } 19 | 20 | //Add to end of list 21 | insertLast(data) { 22 | let node = new Node(data); 23 | let current; 24 | //if list is empty, make new node the head 25 | if (this.size === 0) { 26 | this.head = node; 27 | } else { 28 | //select head as current 29 | current = this.head; 30 | //go to end of list 31 | while (current.next) { 32 | current = current.next; 33 | } 34 | //add new node as next value of the last node 35 | current.next = node; 36 | } 37 | this.size++; 38 | } 39 | 40 | //Remove first item in list 41 | removeFirst() { 42 | if (this.size !== 0) { 43 | this.head = this.head.next; 44 | this.size--; 45 | 46 | if (this.size === 0) { 47 | this.head = null; 48 | } 49 | } 50 | } 51 | 52 | //Remove last item in list 53 | removeLast() { 54 | let current, previous; 55 | if (this.size !== 0) { 56 | if (this.size === 1) { 57 | this.head = null; 58 | } else { 59 | current = this.head; 60 | //go to end of list 61 | while (current.next) { 62 | previous = current; 63 | current = current.next; 64 | } 65 | //remove last node (sets pre) 66 | previous.next = null; 67 | } 68 | this.size--; 69 | } 70 | } 71 | 72 | //Find index of item in list 73 | findIndexOf(data) { 74 | let idx = 0; 75 | //set current to first node 76 | let current = this.head; 77 | //iterate over list 78 | while (current) { 79 | if (current.data === data) { 80 | console.log(idx) 81 | //return index of item 82 | return idx; 83 | } 84 | //increase index by one 85 | idx++; 86 | //move to next node and recheck 87 | current = current.next; 88 | } 89 | console.log(-1); 90 | //not found 91 | return -1; 92 | } 93 | 94 | //Print Linked list data 95 | printListData() { 96 | //set current to first node 97 | let current = this.head; 98 | //iterate over list 99 | while (current) { 100 | console.log(current.data); 101 | current = current.next; 102 | } 103 | } 104 | 105 | //clear list 106 | clearList() { 107 | this.head = null; 108 | this.size = 0; 109 | } 110 | } 111 | 112 | const list = new LinkedList(); 113 | 114 | list.insertLast(400); 115 | list.insertLast(500); 116 | list.insertFirst(600); 117 | list.findIndexOf(500) 118 | 119 | 120 | console.log(list); 121 | 122 | list.printListData(); 123 | 124 | -------------------------------------------------------------------------------- /Queue/arrayQueue.js: -------------------------------------------------------------------------------- 1 | class Queue{ 2 | constructor() { 3 | this.items = []; 4 | } 5 | 6 | enqueue(data) { 7 | //add data to end of queue 8 | this.items.push(data); 9 | } 10 | 11 | dequeue() { 12 | //if empty do nothing else remove first item 13 | if (this.items.length === 0) { 14 | return; 15 | } 16 | this.items.shift() 17 | } 18 | 19 | peek() { 20 | //if not empty return first item 21 | if (this.items.length === 0) { 22 | return "Empty queue"; 23 | } 24 | return this.items[0]; 25 | } 26 | } 27 | 28 | let queue = new Queue(); 29 | queue.enqueue(5); 30 | queue.enqueue(8); 31 | queue.enqueue(10); 32 | queue.dequeue(); 33 | console.log(queue.peek()); 34 | console.log(queue) -------------------------------------------------------------------------------- /Queue/linkedlistQueue.js: -------------------------------------------------------------------------------- 1 | class Node { 2 | constructor(data, next = null) { 3 | this.data = data; 4 | this.next = next; 5 | } 6 | } 7 | 8 | class Queue { 9 | constructor() { 10 | this.head = null; 11 | this.tail = null; 12 | } 13 | 14 | //add item to queue 15 | enqueue(data) { 16 | let node = new Node(data); 17 | //if empty, set new node as head and tail 18 | if (this.tail == null) { 19 | this.head = node; 20 | this.tail = node; 21 | return; 22 | } 23 | //add node as last item in queue 24 | this.tail.next = node; 25 | //set node as tail 26 | this.tail = node; 27 | } 28 | 29 | //remove item from queue 30 | dequeue() { 31 | //if empty, do nothing 32 | if (this.head == null) { 33 | return; 34 | } 35 | //remove cureent head and set head to next item in queue 36 | this.head = this.head.next; 37 | 38 | // set tail to null if queue is emptied 39 | if (this.head == null) { 40 | this.tail = null; 41 | } 42 | } 43 | 44 | //return first item in queue 45 | peek() { 46 | if (this.head == null) { 47 | return "Queue is empty"; 48 | } 49 | return this.head.data; 50 | } 51 | } 52 | 53 | // let queue = new Queue(); 54 | // queue.enqueue(5); 55 | // queue.enqueue(8); 56 | // queue.enqueue(10); 57 | // queue.enqueue(29); 58 | // queue.dequeue(); 59 | // queue.dequeue(); 60 | // queue.dequeue(); 61 | // queue.dequeue(); 62 | // queue.dequeue(); 63 | // console.log(queue.peek()); 64 | // console.log(queue) -------------------------------------------------------------------------------- /Queue/priorityQueue.js: -------------------------------------------------------------------------------- 1 | class Item { 2 | constructor(data, number) { 3 | this.data = data; 4 | this.number = number; 5 | } 6 | } 7 | 8 | class PriorityQueue { 9 | constructor() { 10 | this.items = []; 11 | } 12 | 13 | enqueue(data, number) { 14 | let item = new Item(data, number); 15 | let addedFlag = false; 16 | 17 | //loop through array 18 | for (let idx = 0; idx < this.items.length; idx++) { 19 | //if new item has a higher priority 20 | //add new item before current item 21 | if (this.items[idx].number > item.number) { 22 | this.items.splice(idx, 0, item); 23 | addedFlag = true; 24 | break; 25 | } 26 | } 27 | //default action is to add item at the end of queue 28 | if (!addedFlag) { 29 | this.items.push(item); 30 | } 31 | } 32 | 33 | dequeue() { 34 | //if empty do nothing else remove first item 35 | if (this.items.length === 0) { 36 | return; 37 | } 38 | this.items.shift() 39 | } 40 | 41 | peek() { 42 | //if not empty return first item 43 | if (this.items.length === 0) { 44 | return "Empty queue"; 45 | } 46 | return this.items[0].data; 47 | } 48 | } 49 | 50 | const queue = new PriorityQueue(); 51 | queue.enqueue(3, 4); 52 | queue.enqueue(6, 5); 53 | queue.enqueue(7, 3); 54 | queue.enqueue(8, 1); 55 | queue.dequeue() 56 | console.log(queue.peek()) 57 | 58 | console.log(queue); 59 | -------------------------------------------------------------------------------- /QuickSort/README.md: -------------------------------------------------------------------------------- 1 | # QuickSort 2 | 3 | A divide-and-conquer sorting algorithm that recursively partitions a list into smaller sublists based on a chosen pivot. 4 | 5 | - **Input** - Unsorted list of elements 6 | - **Output** - Sorted list of elements 7 | 8 | ## Algorithm 9 | 10 | 1. Select a **pivot** element from the list. 11 | 2. Partition the list into two sublists: 12 | - Elements smaller than the pivot. 13 | - Elements greater than or equal to the pivot. 14 | 3. Recursively apply QuickSort to the sublists. 15 | 4. Combine the sorted sublists and pivot to form the final sorted list. 16 | 17 | **Time Complexity**: 18 | 19 | - Best/Average Case: O($n \log n$) 20 | - Worst Case (when the pivot is poorly chosen): O($n^2$) 21 | -------------------------------------------------------------------------------- /QuickSort/qs.js: -------------------------------------------------------------------------------- 1 | function swap(arr, leftIndex, rightIndex) { 2 | const temp = arr[leftIndex]; 3 | arr[leftIndex] = arr[rightIndex]; 4 | arr[rightIndex] = temp; 5 | } 6 | 7 | function partition(arr, left, right) { 8 | let pivot = arr[Math.floor((right + left) / 2)], //middle element 9 | i = left, //left pointer 10 | j = right; //right pointer 11 | while (i <= j) { 12 | // while left pointer is less than pivot 13 | // move pointer to the right 14 | while (arr[i] < pivot) { 15 | i++; 16 | } 17 | // while righ pointer is greater than pivot 18 | // move pointer to the left 19 | while (arr[j] > pivot) { 20 | j--; 21 | } 22 | 23 | // if left pointer is less than or equal to right pointe 24 | // swap elements 25 | // increment left pointer n decrement right pointer 26 | if (i <= j) { 27 | swap(arr, i, j); //sawpping two elements 28 | i++; 29 | j--; 30 | } 31 | } 32 | return i; // index of left pointer 33 | } 34 | 35 | function quickSort(arr, left, right) { 36 | let index; 37 | // empty array or single element array considered sorted 38 | if (arr.length > 1) { 39 | index = partition(arr, left, right); //index returned from partition 40 | if (left < index - 1) { //more elements on the left side of the pivot 41 | quickSort(arr, left, index - 1); 42 | } 43 | if (index < right) { //more elements on the right side of the pivot 44 | quickSort(arr, index, right); 45 | } 46 | } 47 | return arr; 48 | } 49 | 50 | 51 | let arr = [4, 2, 5, 1, 3]; 52 | console.log(quickSort(arr, 0, arr.length - 1)); -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Data Structures and Algorithms :rocket: 2 | 3 | Data Structures and Algorithms implemented in: 4 | 5 | 1. JavaScript 6 | 2. Python 7 | 3. R 8 | 9 | Implemented Algorithms: 10 | 11 | 1. Binary Search 12 | 13 | **Note** - the algorithms/data structures below are currently implemented in JS. An update is pending and in progress. 14 | 15 | ## Linked Lists 16 | 17 | **Implementations** 18 | 19 | 1. Add 20 | * Add to start of list 21 | * Add to end of list 22 | 2. Remove 23 | * Remove first 24 | * Remove last 25 | 3. Find index of 26 | 4. Print List 27 | 5. Clear List 28 | 29 | ## Stack 30 | 31 | Implemented with linked list and array as storage mechanisms. 32 | 33 | **Implementations** 34 | 35 | 1. Push 36 | 2. Pop 37 | 3. Peek 38 | 4. Postfix Algorithm 39 | 40 | ## Queue 41 | 42 | Implemented with linked list and array as storage mechanisms. 43 | 44 | **Implementations** 45 | 46 | 1. Enqueue 47 | 2. Dequeue 48 | 3. Peek 49 | 4. Priority Queue 50 | 51 | ## Binary Search Tree 52 | **Implementations** 53 | 1. Add 54 | 2. Find 55 | 3. Remove 56 | 3. Tree Traversal 57 | * pre-order 58 | * in-order 59 | * post-order 60 | 61 | 62 | ## Hash Tables 63 | **Implementations** 64 | 1. Hashing 65 | 2. Add 66 | 3. Remove 67 | 4. Find 68 | 69 | ## Sorting Algorithms 70 | **Implementations** 71 | 1. Bubble sort 72 | 2. Selection Sort 73 | 3. Insertion Sort 74 | 4. Merge Sort 75 | 5. Quick Sort -------------------------------------------------------------------------------- /SelectionSort/README.md: -------------------------------------------------------------------------------- 1 | # Selection Sort 2 | 3 | A sorting algorithm that repeatedly finds the smallest element (or largest) from the unsorted portion of a list and moves it to the sorted portion. 4 | 5 | - Input - Unsorted list of elements 6 | 7 | - Output - Sorted list of elements 8 | 9 | ## Algorithm 10 | 11 | 1. Start from the first element and assume it is the minimum. 12 | 2. Repeat for each element in the list: 13 | 1. Find the smallest element in the remaining unsorted portion. 14 | 2. Swap it with the first unsorted element. 15 | 3. Continue until the entire list is sorted. 16 | 17 | Time Complexity: O($n^2$) 18 | -------------------------------------------------------------------------------- /SelectionSort/ss.js: -------------------------------------------------------------------------------- 1 | function selectionSort(arr) { 2 | for (let i = 0; i < arr.length; i++) { 3 | for (let j = i + 1; j < arr.length; j++) { 4 | if (arr[j] < arr[i]) { 5 | const swapElement = arr[i]; 6 | arr[i] = arr[j]; 7 | arr[j] = swapElement; 8 | } 9 | } 10 | } 11 | 12 | return arr; 13 | } 14 | 15 | 16 | 17 | let arr = [4, 2, 5, 1, 3]; 18 | console.log(selectionSort(arr)) -------------------------------------------------------------------------------- /SetAlgorithms/intersection.js: -------------------------------------------------------------------------------- 1 | function intersection(setA, setB) { 2 | let result = new Set(); 3 | for (let elem of setA) { 4 | if (setB.has(elem)){ 5 | result.add(elem); 6 | } 7 | } 8 | return result; 9 | } 10 | 11 | let setA = new Set([1, 2, 3]); 12 | let setB = new Set([2, 3, 4]); 13 | console.log(intersection(setA, setB)); -------------------------------------------------------------------------------- /SetAlgorithms/setDifference.js: -------------------------------------------------------------------------------- 1 | function setDifference(setA, setB) { 2 | let result = new Set(setA); 3 | for (let item of setB) { 4 | result.delete(item); 5 | } 6 | return result; 7 | } 8 | 9 | let setA = new Set([2, 3, 4]); 10 | let setB = new Set([3, 4, 5]); 11 | console.log(setDifference(setA, setB)); -------------------------------------------------------------------------------- /SetAlgorithms/symmetricDifference.js: -------------------------------------------------------------------------------- 1 | function symmetricDifference(setA, setB) { 2 | let difference = new Set(setA); 3 | for (let elem of setB) { 4 | if (difference.has(elem)) { 5 | difference.delete(elem); 6 | } else { 7 | difference.add(elem) 8 | } 9 | } 10 | return difference; 11 | } 12 | 13 | let setA = new Set([1, 2, 3]); 14 | let setB = new Set([2, 3, 4]); 15 | console.log(symmetricDifference(setA, setB)); -------------------------------------------------------------------------------- /SetAlgorithms/union.js: -------------------------------------------------------------------------------- 1 | function union(setA, setB) { 2 | let result = new Set(setA); 3 | for (let elem of setB) { 4 | result.add(elem); 5 | } 6 | return result; 7 | } 8 | 9 | let setA = new Set([1, 2, 3]); 10 | let setB = new Set([3, 4, 5]); 11 | console.log(union(setA, setB)); -------------------------------------------------------------------------------- /SortingAlgorithm/bubblesort.js: -------------------------------------------------------------------------------- 1 | function bubbleSort(arr) { 2 | let swapCounter = 1; 3 | 4 | while (swapCounter) { 5 | swapCounter = 0; 6 | for (let i = 0; i < arr.length - 1; i++) { 7 | if (arr[i] > arr[i + 1]) { 8 | const swapElement = arr[i]; 9 | arr[i] = arr[i + 1]; 10 | arr[i + 1] = swapElement; 11 | swapCounter = 1; 12 | } 13 | } 14 | } 15 | 16 | return arr; 17 | } 18 | 19 | let arr = [64, 34, 25, 12, 22, 11, 90]; 20 | console.log(bubbleSort(arr)) 21 | -------------------------------------------------------------------------------- /SortingAlgorithm/insertionsort.js: -------------------------------------------------------------------------------- 1 | function insertionSort(arr) { 2 | for (let i = 1; i < arr.length; i++){ 3 | let unsorted = arr[i]; 4 | let idx = i - 1; 5 | 6 | while (idx >= 0 && unsorted < arr[idx]) { 7 | arr[idx + 1] = arr[idx]; 8 | idx -= 1; 9 | } 10 | arr[idx + 1] = unsorted; 11 | } 12 | return arr; 13 | } 14 | 15 | let arr = [4, 2, 5, 1, 3]; 16 | console.log(insertionSort(arr)) -------------------------------------------------------------------------------- /SortingAlgorithm/mergesort.js: -------------------------------------------------------------------------------- 1 | function mergeSort(arr) { 2 | let length = arr.length 3 | 4 | // if n is not > 1 5 | // list is considered sorted 6 | if (length === 1) { 7 | return arr; 8 | } 9 | 10 | let midIdx = Math.ceil(length / 2); 11 | let leftHalf = arr.slice(0, midIdx); 12 | let rightHalf = arr.slice(midIdx, length); 13 | 14 | leftHalf = mergeSort(leftHalf); 15 | rightHalf = mergeSort(rightHalf); 16 | 17 | return merge(leftHalf, rightHalf) 18 | } 19 | 20 | // merge both halfs 21 | function merge(leftHalf, rightHalf) { 22 | const sorted = [] 23 | while (leftHalf.length > 0 && rightHalf.length > 0) { 24 | const leftItem = leftHalf[0] 25 | const rightItem = rightHalf[0] 26 | 27 | if (leftItem > rightItem) { 28 | sorted.push(rightItem) 29 | rightHalf.shift() 30 | } else { 31 | sorted.push(leftItem); 32 | leftHalf.shift() 33 | } 34 | } 35 | 36 | // if left half is not empty 37 | while (leftHalf.length !== 0) { 38 | sorted.push(leftHalf[0]) 39 | leftHalf.shift() 40 | } 41 | // if right half is not empty 42 | while (rightHalf.length !== 0) { 43 | sorted.push(rightHalf[0]) 44 | rightHalf.shift() 45 | } 46 | 47 | return sorted; 48 | } 49 | 50 | let arr = [4, 2, 5, 1, 3]; 51 | console.log(mergeSort(arr)); -------------------------------------------------------------------------------- /Stack/arrayStack.js: -------------------------------------------------------------------------------- 1 | class Stack { 2 | constructor() { 3 | this.items = []; 4 | this.size = -1; 5 | } 6 | 7 | push(data) { 8 | //if an item is provided 9 | if (data) { 10 | //add item to array 11 | this.items.push(data); 12 | //increase size 13 | this.size++; 14 | } 15 | return; 16 | } 17 | 18 | pop() { 19 | //if empty 20 | if (this.size === -1) { 21 | return "UnderFlow"; 22 | } else { 23 | this.size--; 24 | //return top item in stack 25 | return this.items.pop(); 26 | } 27 | } 28 | 29 | peek() { 30 | //if empty 31 | if (this.size === -1) { 32 | return "Empty stack"; 33 | } 34 | //return top item in stack 35 | return this.items[this.size]; 36 | } 37 | } 38 | 39 | // let stack = new Stack(); 40 | // stack.push(3); 41 | // stack.push(5); 42 | // stack.push(7); 43 | // console.log(stack.pop());//7 44 | // console.log(stack.peek());//5 45 | // console.log(stack)//[3, 5] 46 | 47 | module.exports = Stack; 48 | -------------------------------------------------------------------------------- /Stack/linkedlistStack.js: -------------------------------------------------------------------------------- 1 | class Node { 2 | constructor(data, next = null) { 3 | this.data = data; 4 | this.next = next; 5 | } 6 | } 7 | 8 | class Stack { 9 | constructor() { 10 | this.head = null; 11 | this.size = 0; 12 | } 13 | 14 | 15 | //add data to stack 16 | //adds on top of stack 17 | push(data) { 18 | this.head = new Node(data, this.head); 19 | this.size++; 20 | } 21 | 22 | //remove data on top of stack 23 | //returns removed data 24 | pop() { 25 | if (this.size === 0) { 26 | return; 27 | } else { 28 | //select top node 29 | let poppedNode = this.head; 30 | //make second data in stack top node 31 | this.head = this.head.next; 32 | //clear popped node's link 33 | poppedNode.next = null; 34 | this.size--; 35 | // console.log(poppedNode); 36 | return poppedNode.data; 37 | } 38 | } 39 | 40 | //return head node data 41 | peek() { 42 | if (this.size === 0) { 43 | return; 44 | } else { 45 | // console.log(this.head.data) 46 | return this.head.data; 47 | } 48 | 49 | } 50 | 51 | //print data in stack 52 | printStackData() { 53 | //set current to first node 54 | let top = this.head; 55 | if (this.size === 0) { 56 | console.log("Stack Underflow") 57 | } else { 58 | //iterate over list 59 | while (top) { 60 | console.log(top.data); 61 | top = top.next; 62 | } 63 | return; 64 | } 65 | 66 | } 67 | 68 | clear() { 69 | this.head = null; 70 | this.size = 0; 71 | } 72 | } 73 | 74 | let stack = new Stack(); 75 | stack.push(70); 76 | stack.push(80); 77 | stack.push(90); 78 | stack.pop(); 79 | stack.peek(); 80 | stack.printStackData(); 81 | -------------------------------------------------------------------------------- /Stack/postfixCalc.js: -------------------------------------------------------------------------------- 1 | const Stack = require('./arrayStack') 2 | 3 | function postFixCalc(expression) { 4 | //create new stack 5 | let stack = new Stack(); 6 | 7 | //loop through each character in provided expression 8 | for (let idx = 0; idx < expression.length; idx++) { 9 | //store each character 10 | let token = expression[idx]; 11 | 12 | //if it's a number, push to stack 13 | //else pop right side and left side, perform operation and push to stack 14 | if (!isNaN(token)) { 15 | stack.push(Number(token)); 16 | } else { 17 | let rhs = stack.pop(); 18 | let lhs = stack.pop(); 19 | //if right or left side is not available 20 | if (rhs === "UnderFlow" || lhs === "UnderFlow" ) { 21 | return "Can't perform postfix calculation"; 22 | } 23 | switch (token) { 24 | case '+': 25 | stack.push(lhs + rhs); 26 | break; 27 | case '-': 28 | stack.push(lhs - rhs); 29 | break; 30 | case '*': 31 | stack.push(lhs * rhs); 32 | break; 33 | case '/': 34 | stack.push(lhs / rhs); 35 | break; 36 | case '%': 37 | stack.push(lhs % rhs); 38 | break; 39 | } 40 | } 41 | 42 | }; 43 | 44 | return stack.pop(); 45 | } 46 | 47 | console.log(postFixCalc('567*+1-')) 48 | 49 | --------------------------------------------------------------------------------