diff --git a/javascript/code-challenges/merge-sort/README.md b/javascript/code-challenges/merge-sort/README.md new file mode 100644 index 0000000..20ed900 --- /dev/null +++ b/javascript/code-challenges/merge-sort/README.md @@ -0,0 +1,61 @@ +# Challenge Summary +Trace the algorithm by stepping through the process with the provided sample array. Write a working, tested implementation of merge sort based on the pseudocode provided. + +``` +ALGORITHM Mergesort(arr) + DECLARE n <-- arr.length + + if n > 1 + DECLARE mid <-- n/2 + DECLARE left <-- arr[0...mid] + DECLARE right <-- arr[mid...n] + // sort the left side + Mergesort(left) + // sort the right side + Mergesort(right) + // merge the sorted left and right sides together + Merge(left, right, arr) + +ALGORITHM Merge(left, right, arr) + DECLARE i <-- 0 + DECLARE j <-- 0 + DECLARE k <-- 0 + + while i < left.length && j < right.length + if left[i] <= right[j] + arr[k] <-- left[i] + i <-- i + 1 + else + arr[k] <-- right[j] + j <-- j + 1 + + k <-- k + 1 + + if i = left.length + set remaining entries in arr to remaining values in right + else + set remaining entries in arr to remaining values in left +``` + + + +## Approach & Efficiency +| Time Complexity | Space Complexity | +| ---- | ---- | +| O(n log n) | 1 | + +### Run Solution + +```sh +# Install dependencies +npm install + +# run jest tests for stack-queue-pseudo +npm test merge-sort.js +``` + +## Sources + +[JavaScript Algorithms and Data Structures Masterclass - Merge Sort](https://www.udemy.com/course/js-algorithms-and-data-structures-masterclass/) + +[Merge Sort](https://www.geeksforgeeks.org/merge-sort/) \ No newline at end of file diff --git a/javascript/code-challenges/merge-sort/merge-sort.js b/javascript/code-challenges/merge-sort/merge-sort.js new file mode 100644 index 0000000..ad56728 --- /dev/null +++ b/javascript/code-challenges/merge-sort/merge-sort.js @@ -0,0 +1,48 @@ +'use strict' + +// Merge arrays +const merge = (arr1, arr2) => { + // Given two sorted arrays it should return one array sorted + // It should run in O(n+m) time and O(n+m) space + // It should not modify the parameters passed to it. + let results = [] + let i = 0 + let j = 0 + + // While there are still values in both arrays + while(i < arr1.length && j < arr2.length) { + if(arr2[j] > arr1[i]) { + results.push(arr1[i]) + i++ + } else { + results.push(arr2[j]) + j++ + } + } + + // While arr2 is empty + while(i < arr1.length) { + results.push(arr1[i]) + i++ + } + + // While arr1 is empty + while(j < arr2.length) { + results.push(arr2[j]) + j++ + } + + return results +} + +const _mergeSort = (arr) => { + if(arr.length <= 1) return arr + let mid = Math.floor(arr.length / 2) + let left = _mergeSort(arr.slice(0, mid)) + let right = _mergeSort(arr.slice(mid)) + return merge(left, right) +} + +module.exports = { + _mergeSort, +} diff --git a/javascript/code-challenges/merge-sort/merge-sort.test.js b/javascript/code-challenges/merge-sort/merge-sort.test.js new file mode 100644 index 0000000..dc183d6 --- /dev/null +++ b/javascript/code-challenges/merge-sort/merge-sort.test.js @@ -0,0 +1,28 @@ +'use strict' + +const { it } = require('eslint/lib/rule-tester/rule-tester') +const { _mergeSort } = require('./merge-sort') + +describe('Given Merge Sort', () => { + describe('When Sorting', () => { + it('Then should handle whole numbers', () => { + expect(_mergeSort([0,5,1,4,2,3])).toStrictEqual([0,1,2,3,4,5]) + }) + + it('Then should hanlde floating numbers', () => { + expect(_mergeSort([0.1, 5.1, 1.1, 4.1, 2.1, 3.1])).toStrictEqual([0.1, 1.1, 2.1, 3.1, 4.1, 5.1]) + }) + + it('Then should handle negatives', () => { + expect(_mergeSort([0, -5, -1, -4, -2, -3])).toStrictEqual([-5,-4,-3,-2,-1,0]) + }) + + it('Then should handle strings', () => { + expect(_mergeSort(['d', 'a', 'c', 'b'])).toStrictEqual(['a', 'b', 'c', 'd']) + }) + + it('Then should handle duplicates', () =>{ + expect(_mergeSort([1,2,1,2,3,4,3,4])).toStrictEqual([1,1,2,2,3,3,4,4]) + }) + }) +}) diff --git a/javascript/code-challenges/trees/binary-tree.js b/javascript/code-challenges/trees/binary-tree.js index dd5a12e..cd0f35f 100644 --- a/javascript/code-challenges/trees/binary-tree.js +++ b/javascript/code-challenges/trees/binary-tree.js @@ -5,6 +5,8 @@ class BinaryTree{ this.root = root } + // Left will always come before the Right + // (Root, Left, Right) preOrder() { let results = [] @@ -18,6 +20,7 @@ class BinaryTree{ return results } + // (Left, Root, Right) inOrder() { let results = [] @@ -31,6 +34,7 @@ class BinaryTree{ return results } + // (Left, Right, Root) postOrder() { let results = [] diff --git a/javascript/code-challenges/trees/binary-tree.test.js b/javascript/code-challenges/trees/binary-tree.test.js index 74f140b..4881c6d 100644 --- a/javascript/code-challenges/trees/binary-tree.test.js +++ b/javascript/code-challenges/trees/binary-tree.test.js @@ -43,30 +43,30 @@ beforeAll(() => { tree = new BinaryTree(one) }) -let preRes = [1, 2, 6, 7, 8, 9, 3, 4, 5] -let inRes = [6, 8, 7, 9, 2, 1, 4, 3, 5] -let postRes = [8, 9, 7, 6, 2, 4, 5, 3, 1] -let breadthFirstRes = [1, 2, 3, 6, 4, 5, 7, 8, 9] +let preOrderResult = [1, 2, 6, 7, 8, 9, 3, 4, 5] +let inOrderResults = [6, 8, 7, 9, 2, 1, 4, 3, 5] +let postOrderResults = [8, 9, 7, 6, 2, 4, 5, 3, 1] +let breadthFirstResults = [1, 2, 3, 6, 4, 5, 7, 8, 9] describe('Binary Tree Traversal', () => { it('preOrder properly traverses and returns result', () => { let preOrder = tree.preOrder() - expect(preOrder).toEqual(preRes) + expect(preOrder).toEqual(preOrderResult) }) it('inOrder properly traverses and returns result', () => { let inOrder = tree.inOrder() - expect(inOrder).toEqual(inRes) + expect(inOrder).toEqual(inOrderResults) }) it('postOrder properly traverses and returns result', () => { let postOrder = tree.postOrder() - expect(postOrder).toEqual(postRes) + expect(postOrder).toEqual(postOrderResults) }) it('breadthFirst properly traverses and returns results', () => { let breadthFirst = tree.breadthFirst() - expect(breadthFirst).toEqual(breadthFirstRes) + expect(breadthFirst).toEqual(breadthFirstResults) }) it('breadthFirst throws error on empty tree', () => {