diff --git a/README.md b/README.md index 4a870ccfed..f0e90fc8d3 100644 --- a/README.md +++ b/README.md @@ -301,7 +301,8 @@ npm test -- 'playground' ### References -[▶ Data Structures and Algorithms on YouTube](https://www.youtube.com/playlist?list=PLLXdhg_r2hKA7DPDsunoDZ-Z769jWn4R8) +- [▶ Data Structures and Algorithms on YouTube](https://www.youtube.com/playlist?list=PLLXdhg_r2hKA7DPDsunoDZ-Z769jWn4R8) +- [✍🏻 Data Structure Sketches](https://okso.app/showcase/data-structures) ### Big O Notation diff --git a/src/algorithms/search/exponential-search/README.md b/src/algorithms/search/exponential-search/README.md new file mode 100644 index 0000000000..f0f7b7d048 --- /dev/null +++ b/src/algorithms/search/exponential-search/README.md @@ -0,0 +1,16 @@ +# Exponential Search + +In computer science, an exponential search is an algorithm.There are numerous ways to implement this with the most common being to determine a range that the search key +resides in and performing a binary search within that range. This takes O(log i) where i is the position of the search key in the list, if the search key is in the list, +or the position where the search key should be, if the search key is not in the list.Exponential search can also be used to search in bounded lists. Exponential search +can even out-perform more traditional searches for bounded lists, such as binary search, when the element being searched for is near the beginning of the array. + +![Exponential Search](https://upload.wikimedia.org/wikipedia/commons/4/45/Exponential_search.svg) + +## Complexity + +**Time Complexity**: `O(log i)` - i is the index of the element being searched for in the list + +## References + +-[Wikipedia](https://en.wikipedia.org/wiki/Exponential_search) diff --git a/src/algorithms/search/exponential-search/__test__/exponentialSearch.test.js b/src/algorithms/search/exponential-search/__test__/exponentialSearch.test.js new file mode 100644 index 0000000000..0816af2b90 --- /dev/null +++ b/src/algorithms/search/exponential-search/__test__/exponentialSearch.test.js @@ -0,0 +1,35 @@ +import exponentialSearch from '../exponentialSearch'; + +describe('exponentialSearch', () => { + it('should search number in sorted array', () => { + expect(exponentialSearch([], 1)).toBe(-1); + expect(exponentialSearch([1], 1)).toBe(0); + expect(exponentialSearch([1, 2], 1)).toBe(0); + expect(exponentialSearch([1, 2], 2)).toBe(1); + expect(exponentialSearch([1, 5, 10, 12], 1)).toBe(0); + expect(exponentialSearch([1, 5, 10, 12, 14, 17, 22, 100], 17)).toBe(5); + expect(exponentialSearch([1, 5, 10, 12, 14, 17, 22, 100], 1)).toBe(0); + expect(exponentialSearch([1, 5, 10, 12, 14, 17, 22, 100], 100)).toBe(7); + expect(exponentialSearch([1, 5, 10, 12, 14, 17, 22, 100], 0)).toBe(-1); + }); + + it('should search object in sorted array', () => { + const sortedArrayOfObjects = [ + { key: 1, value: 'value1' }, + { key: 2, value: 'value2' }, + { key: 3, value: 'value3' }, + { key: 4, value: 'value4' }, + ]; + + const comparator = (a, b) => { + if (a.key === b.key) return 0; + return a.key < b.key ? -1 : 1; + }; + + expect(exponentialSearch([], { key: 1 }, comparator)).toBe(-1); + expect(exponentialSearch(sortedArrayOfObjects, { key: 4 }, comparator)).toBe(3); + expect(exponentialSearch(sortedArrayOfObjects, { key: 1 }, comparator)).toBe(0); + expect(exponentialSearch(sortedArrayOfObjects, { key: 2 }, comparator)).toBe(1); + expect(exponentialSearch(sortedArrayOfObjects, { key: 3 }, comparator)).toBe(2); + }); +}); diff --git a/src/algorithms/search/exponential-search/exponentialSearch.js b/src/algorithms/search/exponential-search/exponentialSearch.js new file mode 100644 index 0000000000..7d6b3c5683 --- /dev/null +++ b/src/algorithms/search/exponential-search/exponentialSearch.js @@ -0,0 +1,56 @@ +import Comparator from '../../../utils/comparator/Comparator'; + +/** + * Binary search implementation. + * + * @param {*[]} sortedArray + * @param {*} startIndex + * @param {*} endIndex + * @param {*} seekElement + * @param {function(a, b)} [comparatorCallback] + * @return {number} + */ + +function binarySearch(sortedArray, startIndex, endIndex, seekElement, comparatorCallback) { + const comparator = new Comparator(comparatorCallback); + if (endIndex >= startIndex) { + const middleIndex = startIndex + Math.floor((endIndex - startIndex) / 2); + // If the element is present at the middle itself + if (comparator.equal(sortedArray[middleIndex], seekElement)) { + return middleIndex; + } + // If element is smaller than middleIndex, then it can only be present n left subarray + if (comparator.greaterThan(sortedArray[middleIndex], seekElement)) { + return binarySearch(sortedArray, startIndex, middleIndex - 1, seekElement, comparatorCallback); + } + // Else the element can only be present in right subarray + return binarySearch(sortedArray, middleIndex + 1, endIndex, seekElement, comparatorCallback); + } + // We reach here when element is not present in array + return -1; +} +/** + * Exponential search implementation. + * + * @param {*[]} sortedArray + * @param {*} seekElement + * @param {function(a, b)} [comparatorCallback] + * @return {number} + */ +export default function exponentialSearch(sortedArray, seekElement, comparatorCallback) { + const comparator = new Comparator(comparatorCallback); + const length = sortedArray.length; + // If element is present at first location itself + if (sortedArray.length !== 0) { + if (comparator.equal(sortedArray[0], seekElement)){ + return 0; + } + } + // Find range for binary search by repeated doubling + let range = 1; + while (range < length && comparator.lessThanOrEqual(sortedArray[range], seekElement)) { + range *= 2; + } + // Call binary search for the found range. + return binarySearch(sortedArray, range/2, Math.min(range, length - 1), seekElement, comparatorCallback); +} diff --git a/src/data-structures/heap/images/array-representation.jpeg b/src/data-structures/heap/images/array-representation.jpeg index 0a757d7ac0..8914e7102e 100644 Binary files a/src/data-structures/heap/images/array-representation.jpeg and b/src/data-structures/heap/images/array-representation.jpeg differ diff --git a/src/data-structures/heap/images/max-heap.jpeg b/src/data-structures/heap/images/max-heap.jpeg index c818c07f06..c1585d0302 100644 Binary files a/src/data-structures/heap/images/max-heap.jpeg and b/src/data-structures/heap/images/max-heap.jpeg differ diff --git a/src/data-structures/heap/images/min-heap.jpeg b/src/data-structures/heap/images/min-heap.jpeg index 48526d6cdc..646923b2df 100644 Binary files a/src/data-structures/heap/images/min-heap.jpeg and b/src/data-structures/heap/images/min-heap.jpeg differ diff --git a/src/data-structures/queue/images/queue.jpeg b/src/data-structures/queue/images/queue.jpeg index 0e412d550a..579f4d8c83 100644 Binary files a/src/data-structures/queue/images/queue.jpeg and b/src/data-structures/queue/images/queue.jpeg differ diff --git a/src/data-structures/stack/images/stack.jpg b/src/data-structures/stack/images/stack.jpg new file mode 100644 index 0000000000..8c966f276f Binary files /dev/null and b/src/data-structures/stack/images/stack.jpg differ diff --git a/src/data-structures/tree/binary-search-tree/images/binary-search-tree.jpg b/src/data-structures/tree/binary-search-tree/images/binary-search-tree.jpg index f85341d53c..1309e4ee4d 100644 Binary files a/src/data-structures/tree/binary-search-tree/images/binary-search-tree.jpg and b/src/data-structures/tree/binary-search-tree/images/binary-search-tree.jpg differ diff --git a/src/data-structures/tree/images/tree.jpeg b/src/data-structures/tree/images/tree.jpeg index d591972560..c888843d6c 100644 Binary files a/src/data-structures/tree/images/tree.jpeg and b/src/data-structures/tree/images/tree.jpeg differ diff --git a/src/data-structures/trie/images/trie.jpg b/src/data-structures/trie/images/trie.jpg index 8e160b1e8a..001b04f2e7 100644 Binary files a/src/data-structures/trie/images/trie.jpg and b/src/data-structures/trie/images/trie.jpg differ