## Search algorithms and their implementations

As the name suggests, searching algorithms find and retrieve a data item within a data structure. One of the popular use-cases of search algorithms is a search engine. Search engines like Google, AOL, Bing, and Yahoo utilize search algorithms to quickly crawl and index billions of information on the internet to get a user a piece of the requested information. The algorithm’s efficiency determines how fast the search engines can retrieve this information and the abundance of information in their index.

In real life, there are diverse ways we search for items. The way librarians search for books differs from searching for keys in their bag, a word in a dictionary, or a product on a supermarket shelf.
For a computer program, it is no different. Several search algorithms cater to various search processes. They include:

• Linear search
• Binary search
• Jump search
• Sublist search
• Interpolation search
• Fibonacci search

## Linear Search

A linear search starts its search at the beginning of the data structure or list, works its way sequentially through each data element until it reaches the item it is searching for at the end of the list.
It is a simple algorithm but highly inefficient. A list containing a few elements works well with this algorithm, but it becomes inept when we have a considerable number of pieces. Say we have a million features in the list, and the item we need is at the 900,000th index. In such a case, a linear search will go through over 800,000+ items to get to its intended element. That is a lot of time spent processing.
The time complexity for a linear search is `0(n)`. It means execution time increases as the number of elements increases. We use this algorithm with unsorted and sorted elements.

### The Algorithm

```STEP 1:Start searching at first element (i)
STEP 2:Move to the second element and repeat for all elements
STEP 3:At current element, check if it is the required element   IF TRUE     PRINT 'Element found at index number'
STEP 4: Until FOUND == TRUE, or element not found, Repeat search till th
STEP 5:STEP 6:
```

#### Code implementation in Javascript

``````nums = [1, 2, 23, 4, 11, 77, 55, 44, 33, 67]
a = 4

function LinearSearch(nums, a)
{
let results = []
for (let i = 0; i < nums.length; i++)
{
if (nums[i] === a)
{
results.push(i)
}
}
// return -1 when the results array is empty
if (!results)
{
return -1
}
// else return results
return results
}
document.write(LinearSearch(nums, a))``````

#### Code implementation in Python

``````index = -1
nums = [10, 18, 9, 4, 66, 90, 2, 16, 34, 65]
a = 34

def linear_search(nums, a):
i = 0

while i < len(nums):
if nums[i] == a:
globals()['index'] = i
return True

i = i + 1

if linear_search(nums, a):
print('Number found at index', index + 1)# specify the index the number is found at
else :

print(linear_search(nums, a))``````

## Binary Search

Unlike linear search, binary search picks a midpoint in the data structure and divides the elements into two, from that point. It works only with sorted elements since it must determine if the item it is searching for is higher or lower than the other two sides. It chooses the next midpoint of the search based on this.
If the element it searches for is more significant than the midpoint, it moves to the right side with higher values and searches there. If the searched item is lower, it moves to the left side. If the element is equal to the midpoint, it stops its search there. We continue with this process until we get what we want.
Binary search is considered a more efficient algorithm than linear search. It divides elements and quickly discards elements not worth its time and moves to more relevant details. The time complexity is `0(log n)`.
A drawback with Binary Search is that if multiple occurrences of a particular element exist in an array, it does not return the index of that first element but the index closest to it.
An array containing the following values [1,2,3,4,4,5] returns a 3 if we search for 4.

### The Algorithm

`STEP 1:  StartSTEP 2:  Determine the middle item in the list using the formula;  mid = low + (high - low) / 2 to set a midpoint.STEP 3: Compare the value of the middle element to the element being searched for.STEP 4:   IF TRUE, GOTO STEP 7      ELSESTEP 5:  IF target element is > middle element,      THEN   discard the left hand side of the list     ELSESTEP 6:   IF target element is < middle element     THEN       Discard the right hand side of the list     ENDIFSTEP 7:Repeat process 2-6 and iteration until target element == Trueor no more itemSTEP 8:Start`

#### Code implementation in JavaScript

``````//program to write binary search algorithm
function binary_search(num, index)
{ //num is the array, index the target element
let start = 0;
let end = num.length - 1;
while (start <= end)
{
let midpoint = Math.floor((start + end) / 2);
if (num[midpoint] === index)
{
// Found the element
return midpoint;
}
else if (num[midpoint] < index)
{
// if the index is less than the midpoint, the program keeps searching to the right
start = midpoint + 1;
}
else
{
// if the index is greater than the midpoint, the program continues searching to the left
end = midpoint - 1;
}
}
return -1;
}
let num = [1, 2, 3, 4, 5, 6, 7, 8, 9]
let index = 7
document.write(binary_search(num, index))``````

#### Code Implementation in Python

``````sequence_a = [2, 4, 5, 6, 7, 8, 9, 10, 12, 13, 14]
index = 6

def binary_search(arr, item):
beg_index = 0
end_index = len(arr) - 1

while beg_index <= end_index:
midpoint = beg_index + (end_index - beg_index) // 2
midpoint_value = arr[midpoint]
if midpoint_value == item:
return midpoint

elif item < midpoint_value:
end_index = midpoint - 1

else :
beg_index = midpoint + 1

return None

if binary_search(sequence_a, index):
print('Number', index, 'found')
else :

print('At index', binary_search(sequence_a, index))``````

## Fibonacci algorithm

Are you familiar with the mathematical Fibonacci sequence? The Fibonacci algorithm is the same as the Fibonacci sequence and follows the same logic. In programming, the Fibonacci sequence provides an intricate side-view when it comes to determining the difference between loops and recursion.
Fibonacci sequence is a group of numbers, starting from 0 where the next number is an addition of the last number + the current number. So we have:

`0, 1, 1, 2, 3, 5, 13, 21, 34...`

Usually, the first number is initialized to either a 0 or 1, depending on where we want to start counting. Fibonacci algorithms work with three numbers, the first number, the following number after it, and their sum. If we initialize to 0, the following number is 1, and the value of the next number is 0+1, which is 1, after which we add 1 + 1 to give us the following number 2.

`0,1,1,2...`

Calculating for a Fibonacci sequence is calculating the nth term of a set of sequences. The nth term is the sum of the (n-1)th and the (n-2)th term. The formula for this is,

`tn  =  tn-1 + tn-2`

The time complexity for the Fibonacci algorithm is `0(log n)`, just like a binary search. One of its uses is in the financial trade market, where Fibonacci numbers serve as technical indicators.

### Algorithm

`STEP 1:StartSTEP 2:Declare the variables for the first, second, third numbers, increment and nth position (x, y, z, i, n)STEP 3:Initialize the variables, x = 0, y = 1 and c = 2STEP 4:Get the value of the number of terms, nSTEP 5:Get the sum of the first two termsSTEP 6:  Repeat until i<=n    Z = x + y    Print z    x = y, y = z    i = i + 1STEP 7:Stop`

#### Code implementation with Javascript

``````//program to write fibonacci algorithm
function fibonacci_search(num)
{
var x = 1,
y = 0,
z;
while (num >= 0)
{
z = x;
x = x + y;
y = z;
num--;
}
return y;
}
document.write(fibonacci_search(8))``````

#### Code implementation with Python

``````# Fibonnacci sequence solution

def fibonacci(no): #the base
case
if no <= 1:
return no
else :
return (fibonacci(no - 1) + fibonacci(no - 2))
length = int(input("Length of the sequence "))# takes input from the user

if length <= 0:
print("Please enter a number greater than zero")
else :
print("Fibonacci sequence:")
for i in range(length):
print(fibonacci(i))

# output
# Length of the sequence 10# Fibonacci sequence:
# 0,1,1,2,3,5,8,13,21,34``````

## Jump Search Algorithm

Jump search, like binary search, works only with sorted arrays and uses a divide and conquer approach, designed as an improvement over linear search. The algorithm searches for an element by jumping m number of components and determines if the searched term is between the previous and current jump.
To start the process, we need a low and high value, namely, the starting and ending points of the array. The algorithm also has a size n, the size of the array, and a block jump or size m.
If we have an array of 1 - 12 (making the size n = 12), with index 0 to 11, our low value is 1, which is at index 0, and the high value is 12, which is at index 11. If we take our jump block, m, to be 3, the algorithm iterates by jumping over every three elements. So it moves from index 0 - 3, jumps from 3 to 6, and 6 to 9.
At every jump, we compare the elements in the array with the target element and array’s size. We also note the number of jumps the program makes.

Between 0-3, 1 jump

Between 3 - 6, 2 jumps

Between 6 - 9, 3 jumps

Here, it stops. Jumping from 9 - 12 is smaller than the jump size (which is 3). Our last index stops at 11. From index 9, we perform the search linearly, moving from 9 to 10 to 11. This linear movement is still counted as a jump but not of block m. therefore the total number of jumps = 5.
The time Complexity, `O(√n)` is calculated by the number of jumps and the number of elements within each block.

## Related Articles

### Algorithm

`STEP 1:StartSTEP 2:Determine jump size, m with the formular, math.sqrt(n(arr))STEP 3:Start iteration at the beginning of nSTEP 4:When i = 0, start iteration with m jump. Do this until the end of the list (n < i)STEP 5:Compare the target element with elements in the list after each jump.  IF target element == TRUE    STEP 10STEP 6:IF target element less than m, continue jumpSTEP 7:IF target element greater than jump  Stop at the previous jump and perform a linear searchSTEP 8:IF m jump cannot be completed, but there are elements in n, perform a linear searchSTEP 9:IF target element == FALSE,  Exit STEP 10:Exit`

#### Code implementation in JavaScript

``````function jumpSearch(n, element)
{
let len = n.length
//making m the jump block
let m = Math.floor(Math.sqrt(len));
//starting index
let startindex = 0,
currentStep = m;
while (n[Math.min(currentStep, len) - 1] < element)
{
//processing to the next jump if target element not found in the current jump
startindex = currentStep;
currentStep += m;
if (startindex >= len) return -1;
}
//Linear Search block
while (n[startindex] < element)
{
startindex++;
//if we can't find target element in the array
if (startindex == Math.min(currentStep, len)) return -1;
}
if (n[startindex] == element) return startindex
else return -1;
}
let n = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12]
let element = 12;
document.write(jumpSearch(n, element))``````

#### Code implementation in Python

``````import math

def jump_search(n, element):

#n - The array / list
# element - Item that the index needs to find

print("Processing Jump Search")
a = len(n)
m = int(math.sqrt(a))# m = jump block
i = 0

while i != len(n) - 1 and n[i] < element:
print("Processing Batch - {}".format(n[i: i + m]))

if n[i + m - 1] == element:
return i + m - 1

elif n[i + m - 1] > element:
B = n[i: i + m - 1]
return linear_search(B, element, i)
i += m

B = n[i: i + m]
print("Processing Batch - {}".format(B))
return linear_search(B, element, i)``````

The Linear Search function part of the code

``````def linear_search(B, element, loc):
#loc - The Index where the remaining batch begins# B is the derived list
print("\t Starting Linear Search")
i = 0

while i != len(B):
if B[i] == element:
return loc + i
i += 1
return -1

if __name__ == "__main__":

print(jump_search(n, 12))

# prints the index``````

## Sublist Algorithm

The sublist search algorithm determines if there is a sublist in another list. It compares the first list to the second to ascertain if list one is in list two.
If we had a list containing [25, 12, 19, 2] and another that had [14, 25, 33, 12,2, 80, 19, 72], we could immediately see some shared elements. What the sublist algorithm does is to check this in a linear, sequential manner.

### Algorithm

`STEP 1: StartSTEP 2:Declare the variables for the two listsSTEP 3:Take first node of the second listSTEP 4:Match the elements of the first list with this nodeSTEP 5:IF the elements match, return TRUESTEP 6:ELSE, iterate through the first nodeSTEP 7:AND take the second list to the second nodeSTEP 8:Repeat the process until both lists are emptySTEP 9:IF the first list becomes empty,  Return 'List not found'STEP 10:Exit`

#### Code implementation with JavaScript

``````// JavaScript program to find a list in second list
class Node
{
constructor()
{
this.data = 0;
this.next = null;
}
}
// Returns true if first list is present in second list
function findList(list1, list2)
{
var ptr1 = list1,
ptr2 = list2;
// If both linked lists are empty,return true
if (list1 == null && list2 == null) return true;
// Else If one is empty and other is not, return false
if (list1 == null || (list2 != null && second == null)) return false;
// pick nodes one by one
while (list2 != null)
{
// Initialize ptr2 with
// current node of second
ptr2 = list2;
while (ptr1 != null)
{
if (ptr2 == null) return false;
else if (ptr1.data == ptr2.data)
{
ptr1 = ptr1.next;
ptr2 = ptr2.next;
}
// If not equal then break the loop
else break;
}
// Return true if first list gets traversed
if (ptr1 == null) return true;
// Initialize ptr1 with first again
ptr1 = first;
// move to the node of second list
second = second.next;
}
return false;
}
/* Function to print the nodes */
function printNode(node)
{
while (node != null)
{
document.write("%d ", node.data);
node = node.next;
}
}
// The function we need to add new node to linked lists
function newNode(key)
{
var temp = new Node();
temp.data = key;
temp.next = null;
return temp;
}
// Driver Code
/*
Let us create two linked lists to test
the above functions. Created lists
shall be x: 1->2->3->4 y: 1->2->1->2->3->4
*/
var x = newNode(1);
x.next = newNode(2);
x.next.next = newNode(3);
x.next.next.next = newNode(4);
var y = newNode(1);
y.next = newNode(2);
y.next.next = newNode(1);
y.next.next.next = newNode(2);
y.next.next.next.next = newNode(3);
y.next.next.next.next.next = newNode(4);
if (findNode(x, y) == true) document.write("LIST FOUND");

#### Code implementation with Python

``````#Python3 program to find a list in another list
class Node:
def __init__(self, value = 0):

self.value = value
self.next = None

# Returns true
if first list is present in second list
def findList(list1, list2):
if not first and not second:
return True

# If ONLY one of them is empty, #
return False
if not list1 or not list2:
return False

ptr1 = first
ptr2 = second

# Iterate the second list by picking nodes one after the other
while ptr2:

#Initialize 'ptr2'
with current node of 'second'
ptr2 = second

while ptr1:
if not ptr2:
return False
elif ptr1.value == ptr2.value:
ptr1 = ptr1.next
ptr2 = ptr2.next
else:
break

# If 'ptr1' is None / empty, that means the 'first LL' has been completely traversed and matched so return True
if not ptr1:
return True

return False``````

## Interpolation Search Algorithm

The interpolation algorithm is another divide-and-conquer algorithm. It works with a sorted array of uniform distribution.
Unlike the other algorithms, it does not just start a search. Instead, it has a mathematical formula and performs some calculations to determine where to begin that search.
Two conditions are necessary for this algorithm to perform

1. The elements must be sorted
2. The elements of the list must be uniformly distributed. The difference between the elements must be the same.

The formula to get a starting position:

Where,

low is the starting index value
x is the searched element
a is the values of the indexes
High is the last index value of the array

If we have an array of the following values

[1, 4, 7, 10, 13, 16, 19, 21, 24] with a uniform difference of 3, and we need to find 16, here is how we go about it.

Low = 0
High = 24
x = 16
a[l] = 1
a[h] = 26

16 is at index 5. It has taken just one step to find 16.

Sometimes, we might have a large array that is slightly not uniformed. This won't give a perfect answer. We will need to readjust the values of…
The time complexity is `0(log n)` when values are uniformly distributed as `0(n)`, for worst-case when values are not evenly distributed.

### Algorithm

`STEP 1:StartSTEP 2:Declare the variables. x = target elementSTEP 3:Write the formula to calculate the value of the indexSTEP 4:If the value of the x and index == True, the index is returned.STEP 5:If the value is less than the index,  THEN the value of the index is recalculated with adjusted values for the left sub-arraySTEP 6:If the value is higher than the index,  THEN the value of the index is recalculated with adjusted values for the right sub-array.STEP 7:If value of x and index == FALSE  RETURN 'Index not found'STEP 8: Exit`

#### Code implementation with JavaScript

``````//Interpolation code javascript
const arr = [1, 4, 6, 7, 9, 12, 15, 16, 17, 23, 25, 26, 27, 31];
const index = 25;
const interpolation_Search = (arr = [], index) =>
{
let l = 0;
let r = arr.length - 1;
while (l <= r)
{
const a_r = arr[r] - arr[l];
Const a = r - l;
const x = index - arr[left];
if (x < 0)
{
return -1;
}
if (!a_r)
{
return arr[l] === index ? l : -1;
}
const middleIndex = l + Math.floor((x * a) / a_r);
if (arr[middleIndex] === index)
{
return middleIndex;
}
if (arr[middleIndex] < index)
{
l = middleIndex + 1;
}
else
{
r = middleIndex - 1;
}
};
return -1;
};
console.log(interpolation_Search(arr, index));``````

#### Code implementation with Python

``````#program to write interpolation search

def Interpolation_search(arr, index):
low = 0
high = (len(arr) - 1)
while low <= high and index >= arr[low] and index <= arr[high]:
element = low + int(((float(high - low) / (arr[high] - arr[low])) * (index - arr[low])))
if arr[element] == index:
return element
if arr[element] < index:
low = element + 1;
else :
high = element - 1;
return -1

print(Interpolation_search([1, 2, 3, 4, 5, 6, 7, 8], 6))``````

## Conclusion

We hope we’ve given you some good case on how to use Search Algorithms and have mentioned the most popular in their respective JavaScript and Python implementation. Search algorithms are integral part of Algorithmic knowledge in Software Engineering – and the ‘have to know’ for every software engineer!

#### Author

Kris is the Head of Research and Development at CodeCoda and, as he himself says, is constantly seeking better methods of developing and implementing software solutions.
In his previous experience as a software engineer, he has experienced everything from plain assembly code through the optimization of the process of business and functional analysis and the development of Fintech Applications.
During his school years, he won several medals in international competitions in mathematics and computer science. Concerning his professional interests, he pays special attention to algorithms and software development methodologies.