Data Structures and Algorithms using Python
Copyright © 2023 by Rance Necaise
Table Of Contents
Data Structures and Algorithms using Python
Copyright © 2023
by Rance Necaise

6.2 Linear Search

The simplest solution to the sequence search problem is the sequential or linear search algorithm. This technique iterates over the sequence, one item at a time, until the specific item is found or all items have been examined. In Python, a target item can be found in a sequence using the in operator:

if key in theArray :
   print("The key is in the array.")
else :
   print("The key is not in the array.")

The use of the in operator makes our code simple and easy to read but it hides the inner workings. Underneath, the in operator is implemented as a linear search. Consider the unsorted 1-D array of integer values shown in Figure 6.2.1 (a). To determine if value 31 is in the array, the search begins with the value in the first element. Since the first element does not contain the target value, the next element in sequential order is compared to value 31. This process is repeated until the item is found in the sixth position. What if the item is not in the array? For example, suppose we want to search for value 8 in the sample array. The search begins at the first entry as before, but this time every item in the array is compared to the target value. It cannot be determined that the value is not in the sequence until the entire array has been traversed, as illustrated in Figure 6.2.1 (b).

Figure 6.2.1: Performing a linear search on an unsorted array: (a) the target item is found and (b) the item is not in the array.

Finding a Specific Item

The function in the source listing below implements the sequential search algorithm, which results in a boolean value indicating success or failure of the search.

Program Listing
Program: linearsearch.py
  1. def linearSearch( theValues, target ) :
  2.   n = len( theValues )
  3.   for i in range( n ) :    
  4.      # If the target is in the ith element, return True
  5.     if theValues[i] == target
  6.       return True
  7.      
  8.   return False   # If not found, return False.

This is the same operation performed by the Python in operator. A count-controlled loop is used to traverse through the sequence during which each element is compared against the target value. If the item is in the sequence, the loop is terminated and True is returned. Otherwise, a full traversal is performed and False is returned after the loop terminates.

linear search
worst-case: O(n)

To analyze the sequential search algorithm for the worst case, we must first determine what conditions constitute the worst case. Remember, the worst case occurs when the algorithm performs the maximum number of steps. For a sequential search, that occurs when the target item is not in the sequence and the loop iterates over the entire sequence. Assuming the sequence contains n items, the linear search has a worst case time of O(n).

Question 6.2.1

Does the linear search have a best case? If so, when does the best case occur? When does the worst case occur?

Yes.

  • The best case occurs when the target is the first element in the sequence. In that case, the loop terminates after the first iteration.
  • The worst case occurs when the target is not in the sequence. Thus, the loop iterates n times, or once for each element in the sequence.

Searching a Sorted Sequence

A linear search can also be performed on a sorted sequence, which is a sequence containing values in a specific order. For example, the values in the array illustrated in Figure 6.2.2 are in ascending or increasing numerical order. That is, each value in the array is larger than its predecessor.

Figure 6.2.2: The linear search on a sorted array.

A linear search on a sorted sequence works in the same fashion as that for the unsorted sequence, with one exception. It's possible to terminate the search early when the value is not in the sequence instead of always having to perform a complete traversal. For example, suppose we want to search for 8 in the array from Figure 6.2.2. When the fourth item, which is value 10, is examined, we know value 8 cannot be in the sorted sequence or it would come before 10. The implementation of a linear search on a sorted sequence is provided below.

Program Listing
Program: sortedlinear.py
  1. def sortedLinearSearch( theValues, target ) :
  2.   n = len( theValues )
  3.   for i in range( n ) :
  4.      # If the target is found in the ith element, return True    
  5.     if theValues[i] == target :
  6.       return True
  7.      # If target is larger than the ith element,
  8.      # it's not in the sequence.
  9.     elif theValues[i] > target :
  10.       return False
  11.  
  12.   return False   # The item is not in the sequence.

The only modification to the earlier version is the inclusion of a test to determine if the current item within the sequence is larger than the target value. If a larger value is encountered, the loop terminates and False is returned. With the modification to the linear search algorithm, we have produced a better version, but the time-complexity remains the same. The reason is that the worst case occurs when the value is not in the sequence and is larger than the last element. In this case, we must still traverse the entire sequence of n items.

Question 6.2.2

What is the worst case time-complexity for the sortedLinearSearch function?

Select the correct answer below by clicking on the appropriate box.
  1. O(1)
  2. O(log n)
  3. O(n)
  4. O(n2)
The worst case time-complexity for the linear search is still linear even though it is applied to a sorted sequence. In the worst case, it must still examine every element of the sequence.

Finding the Smallest Value

Instead of searching for a specific value in an unsorted sequence, suppose we wanted to search for the smallest value, which is equivalent to applying Python's min function to the sequence. A linear search is performed as before, but this time we must keep track of the smallest value found for each iteration through the loop, as illustrated in in the source listing below.

Program Listing
Program: smallest.py
  1. def findSmallest( theValues ):
  2.   n = len( theValues )
  3.    # Assume the first item is the smallest value.
  4.   smallest = theValues[0]    
  5.    # Determine if any other item in the sequence is smaller.
  6.   for i in range( 1, n ) :
  7.     if theList[i] < smallest :
  8.       smallest = theValues[i]
  9.          
  10.   return smallest       # Return the smallest found.

To prime the loop, we assume the first value in the sequence is the smallest and start the comparisons at the second item. Since the smallest value can occur anywhere in the sequence, we must always perform a complete traversal, resulting in a worst case time of O(n).

Question 6.2.3

Does the findSmallest function have a best case? If so, when does it occur and what is the time-complexity in the best case?

Since the smallest value can occur anywhere within the sequence, we must always perform a complete traversal. Thus, searching for the smallest value within in a sequence does not have a best case.

Page last modified on August 26, 2023, at 01:23 PM