Skip to content
Open
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 4 additions & 5 deletions Search/QuickSelectSearch.js
Original file line number Diff line number Diff line change
Expand Up @@ -18,16 +18,15 @@ export function quickSelectSearch(array, k) {

let from = 0
let to = array.length - 1

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please keep unrelated changes out of this PR

while (from < to) {
let left = from
let right = to
let [left, right] = [from, to]

const pivot = array[Math.ceil((left + right) * 0.5)]

while (left < right) {
if (array[left] >= pivot) {
const tmp = array[left]
array[left] = array[right]
array[right] = tmp
;[array[left], array[right]] = [array[right], array[left]]
--right
} else {
++left
Expand Down
41 changes: 41 additions & 0 deletions Search/SentinelSearch.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
/**
* @function sentinelSearch
Copy link
Collaborator

@appgurueu appgurueu Oct 2, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
* @function sentinelSearch

* @description Sentinel search algorithm for array.
*
* Sentinel linear search is a variation of the standard linear search algorithm used to
* find a target value in an array or list. The basic idea behind this algorithm is to add a
* sentinel value at the end of the array which is equal to the target value we are looking for.
* This helps to avoid checking the array boundary condition during each iteration of the loop,
* as the sentinel value acts as a stopper for the loop.
*
* @param {number[]} array - sorted list of numbers
* @param {number} target - target number to search for
* @return {number | null} - index of the target number in the list, or null if not found
* @see [SentinelSearch](https://www.geeksforgeeks.org/sentinel-linear-search/)
* @example sentinelSearch([1,2,3], 2) => 1
* @example sentinelSearch([4,5,6], 2) => null
* @complexity_analysis
* Time Complexity :
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think just O(n) or omitting it altogether would suffice here. It's pretty trivial to see.

* Worst Case -> The time complexity of the Sentinel Linear Search algorithm is O(n) in the worst case.
* Best Case -> In the best case, when the key is found in the first iteration, the time complexity will be O(1).
* Average Case -> However, the average time complexity is still O(n).
* Auxiliary Space: O(1)
*/

export const sentinelSearch = (array, target) => {
const arrayLength = array.length
if (arrayLength === 0) return null

// Element to be searched is placed at the last index
const last = array[arrayLength - 1]
array[arrayLength - 1] = target

let index = 0
while (array[index] !== target) index++

// Put the last element back
array[arrayLength - 1] = last

if (index < arrayLength - 1 || array[arrayLength - 1] === target) return index
return null
}
69 changes: 30 additions & 39 deletions Search/TernarySearch.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,38 +12,33 @@
*/

function ternarySearchRecursive(arr, key, low = 0, high = arr.length - 1) {
if (high >= low) {
// find the mid1 and mid2
const mid1 = Math.floor(low + (high - low) / 3)
const mid2 = Math.floor(high - (high - low) / 3)
// if low > high => we have searched the whole array without finding the item
if (low > high) return -1

// check if key is found at any mid
if (arr[mid1] === key) {
// return index of key if found
return mid1
}
if (arr[mid2] === key) {
// return index of key if found
return mid2
}
// find the mid1 and mid2
const mid1 = Math.floor(low + (high - low) / 3)
const mid2 = Math.floor(high - (high - low) / 3)

// since the key is not found at mid,
// check in which region it is present
// and repeat the Search operation
// in that region
if (key < arr[mid1]) {
// the key lies in between low and mid1
return ternarySearchRecursive(arr, key, low, mid1 - 1)
} else if (key > arr[mid2]) {
// the key lies in between mid2 and high
return ternarySearchRecursive(arr, key, mid2 + 1, high)
} else {
// the key lies in between mid1 and mid2
return ternarySearchRecursive(arr, key, mid1 + 1, mid2 - 1)
}
// check if key is found at any mid
// return index of key if found
if (arr[mid1] === key) return mid1

// return index of key if found
if (arr[mid2] === key) return mid2

// since the key is not found at mid,
// check in which region it is present
// and repeat the Search operation
// in that region
if (key < arr[mid1]) {
// the key lies in between low and mid1
return ternarySearchRecursive(arr, key, low, mid1 - 1)
} else if (key > arr[mid2]) {
// the key lies in between mid2 and high
return ternarySearchRecursive(arr, key, mid2 + 1, high)
} else {
// if low > high => we have searched the whole array without finding the item
return -1
// the key lies in between mid1 and mid2
return ternarySearchRecursive(arr, key, mid1 + 1, mid2 - 1)
}
}

Expand All @@ -54,14 +49,11 @@ function ternarySearchIterative(arr, key, low = 0, high = arr.length - 1) {
const mid2 = Math.floor(high - (high - low) / 3)

// check if key is found at any mid
if (arr[mid1] === key) {
// return index of key if found
return mid1
}
if (arr[mid2] === key) {
// return index of key if found
return mid2
}
// return index of key if found
if (arr[mid1] === key) return mid1

// return index of key if found
if (arr[mid2] === key) return mid2

// since the key is not found at mid,
// check in which region it is present
Expand All @@ -75,8 +67,7 @@ function ternarySearchIterative(arr, key, low = 0, high = arr.length - 1) {
low = mid2 + 1
} else {
// the key lies in between mid1 and mid2
low = mid1 + 1
high = mid2 - 1
;[low, high] = [mid1 + 1, mid2 - 1]
}
}
// the key was not found
Expand Down
13 changes: 13 additions & 0 deletions Search/test/SentinelSearch.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import { sentinelSearch } from '../SentinelSearch'

describe('Sentinel search', () => {
test.each([
[['o', 'b', 'c'], 'c', 2],
[[1, 2, 3, 4, 5], 4, 3],
[['s', 't', 'r', 'i', 'n', 'g'], 'a', null],
[['1', '2', '3'], '1', 0],
[['4', 'e', '6', '10'], 4, null]
])('of %o , searching for %o, expected %i', (array, target, index) => {
expect(sentinelSearch(array, target)).toStrictEqual(index)
})
})
14 changes: 11 additions & 3 deletions Search/test/TernarySearch.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -29,13 +29,13 @@ test('should return the index of a number in an array of numbers:', () => {
test('should return the index of a string in an array of strings:', () => {
const indexNumber = ternarySearchRecursive(
['Ali', 'Cathrynli', 'Josuke', 'Thomas'],
'Cathrynli'
'Josuke'
)
expect(indexNumber).toBe(1)
expect(indexNumber).toBe(2)
})

test('should return the index of a string in an array of strings:', () => {
const indexNumber = ternarySearchRecursive(
const indexNumber = ternarySearchIterative(
['Ali', 'Cathrynli', 'Josuke', 'Thomas'],
'Josuke'
)
Expand All @@ -49,3 +49,11 @@ test('should return the index of a string in an array of strings:', () => {
)
expect(indexNumber).toBe(-1)
})

test('should return the index of a string in an array of strings:', () => {
const indexNumber = ternarySearchIterative(
['Ali', 'Cathrynli', 'Josuke', 'Thomas'],
'Angela'
)
expect(indexNumber).toBe(-1)
})