DEV Community

Ricardo Borges
Ricardo Borges

Posted on • Originally published at ricardoborges.dev

Starting with search algorithms

Search algorithms that are used to retrieve information from a data structure, in this post I'll describe 3 search algorithms to find an element in lists.

Linear Search

Linear search is the most basic and easier to understand search algorithm, it simply starts from the first element in the list, and check each element to see if it is the element we are searching for, if the element is found returns its position in the list, else returns -1, null or undefined. Since it goes through the entire list, its time complexity is O(n).

function linearSearch(list:number[], n:number): number {
  for(let i=0; i< list.length; i++) {
    if(list[i] === n) return i
  }
}

const list = [2,6,4,8,9,0,1,5]
console.log(linearSearch(list, 1)) // 6
Enter fullscreen mode Exit fullscreen mode

What if we are given a sorted list? The next two algorithms work on sorted lists and are faster than the Linear Search algorithm.

Jump Search

Instead of check element-by-element, This algorithm search block-by-block, so it checks fewer elements.

  1. We start defining a block size
  2. Starting from the beginning of the list, we check the last element of each block, if the element is smaller than the value we are looking for, we jump to the next block.
  3. But, if the last element of the current block is greater than the value we are looking for, we do a linear search in that block.

Jump Search time complexity in the average and worst cases is O(√ n).

function jumpSearch(list:number[], n:number): number {
  const blockSize = Math.floor(Math.sqrt(list.length))
  const start = 0

  while(list[start+blockSize-1] < n) {      
    if(start + blockSize >= list.length) {
        start += list.length - 1 - start
    }else {
        start += blockSize
    }
  }

  for(let i=start; i < start+blockSize-1; i++) {
    if(list[i] === n) return i
  }
}

const sortedList = [1,2,3,4,5,6,7,8,9,10]
console.log(jumpSearch(sortedList, 5)) // 4
Enter fullscreen mode Exit fullscreen mode

Binary Search

This algorithm is also meant for sorted lists, it uses a divide-and-conquer technique, which means it divides the problem into smaller parts that are easier to solve.

  1. Start by checking the element in the middle of the lists, if this element is the element we are searching for returns its position.
  2. If that middle element is greater than the element we are searching for, repeat the first step for the right half.
  3. But, if that middle element is smaller, repeat the first step for the left half.

Notice that this algorithm keeps dividing the sublists into even smaller ones checking only the element in the middle of each sublist, and it might, eventually, wind up with a sublist that contains a single element. Since this algorithm is halving the list at each iteration its time complexity is O(log n).

Worth mentioning that this algorithm is also implemented for a Binary Search Tree.

Here's an recursive implementation of Binary Search without any auxiliary data structures:

function binarySearch(list:number[], n:number, low:number, high:number): number {
  // base case
  if(low > high) return

  let middle = Math.floor((low + high) / 2)

  if(list[middle] === n) return middle

  if(n < list[middle]) return binarySearch(list, n, low, middle-1)

  if(n > list[middle]) return binarySearch(list, n, middle+1, high)
}

const sortedList = [1,2,3,4,5,6,7,8,9,10]
console.log(binarySearch(sortedList, 3, 0, sortedList.length - 1))
Enter fullscreen mode Exit fullscreen mode

Discussion (0)