Searching Arrays 


 

Searching involves looking systemically through the elements of an array.  There are many different searching techniques.  In most cases you need to know not only if a value is in an array, but also where it is located in the array.

==================

Linear Search

In a linear search every element in the array is compared to a search key.

Since the array is in no particular order, it is just as likely that the value will be found in the first element as in the last.

On average, therefore, the program compares the search key with half the elements of the array to locate a value in the array.

The linear search works well for small arrays or for unsorted arrays, but is inefficient for large, sorted arrays. 

In the following example, setOfValues is the array being searched, and searchValue is the value being searched for.  The function index returns the subscript of the element containing the search value.  

Private Function searchArray(ByVal setOfValues() As String, _
                                          ByVal searchValue As String) As Integer
     Dim found As Boolean = False
     Dim index As Integer = 0
     While ((index <= setOfValues.GetUpperBound(0)) And Not found)
          If (searchValue = setOfValues(index)) Then
               found = True
          Else
               index = index + 1
          End If
     End While
     Return IIf(found,index, -1)
End Function

==================

Binary Search

The binary search requires that the array being searched is in sorted order.  The algorithm removes from consideration one half of the elements in the array being searched after each comparison.

  • The algorithm locates the middle element of the array and compares it to the search key. 
  • If they are equal, the search key is found and the array index of that element is returned. 
  • Otherwise, the problem is reduced to searching one half of the array. 
  • If the search key is less than the middle element of the array, the first half of the array is searched, otherwise the second half of the array is searched. 
  • If the search key is not the middle element in the specified subarray, the algorithm is repeated on one quarter of the original array, then one eighth, then one sixteenth, and so on. 
  • The search continues until the search key is equal to the middle element of a subarray or until the subarray consists of one element that is not equal to the search key (i.e., the search key is not found).

The maximum number of comparisons needed for the binary search of any sorted array can be determined by finding the first value of the power of 2 greater than or equal to the number of elements in the array.

  • In a worst-case scenario, searching an array of 1024 elements will take only ten comparisons using a binary search. 
  • Repeatedly dividing 1024 by 2 (because after each comparison we are able to eliminate half of the array) yields the values 512, 256, 128,64, 32, 16, 8, 4, 2 and 1. 
  • The number 1024 (210) is divided by 2 only ten times to get the value 1. 
  • Dividing by 2 is equivalent to one comparison in the binary search algorithm. 
  • An array of one billion elements takes a maximum of 30 comparisons to find the search key. 
  • This is a tremendous increase in performance over the linear search that required comparing the search key on average to half the elements in the array. 
  • For a one billion-element array, this is the difference between an average of 500 million comparisons and a maximum of 30 comparisons! 

==================

Binary Overhead

The tremendous performance gains of the binary search over the linear search do not come without a price. 

Sorting an array is an expensive operation compared to searching an entire array once for an item. 

The overhead of sorting an array becomes worthwhile when the array will need to be searched many times at high speed.

==================

Iterative Example

The figure below presents the iterative version of function binarySearch.

If the searchKey does not match the middle element of a subarray, the low index or high index is adjusted so that a smaller subarray can be searched.

If the searchKey is less than the middle element, the high index is set to middle - 1, and the search is continued on the elements from low to middle - 1.

If the searchKey is greater than the middle element, the low index is set to middle + 1, and the search is continued on the elements from middle + 1 to high.

---------

The example uses an array of 15 elements and a searchKey of 6.

The middle element in each subarray is marked by a red border and an arrow to indicate the element to which the searchKey will be compared.

The first power of 2 greater than the number of elements in this array is 16 (24), so a maximum of four comparisons are required to find the searchKey.

Private Function binarySearch(ByVal mArray() As Integer, _
                                            ByVal searchKey As Integer) As Integer
     Dim found As Boolean = False
    
Dim index As Integer = 0
    
Dim low As Integer = mArray.GetLowerBound(0)
    
Dim high As Integer = mArray.GetUpperBound(0)
    
Dim middle As Integer

    
Do While (low <= high) And Not found
    
     middle = (low + high) \ 2

    
     If (searchKey = mArray(middle)) Then
    
          found = True
    
          index = middle
    
     ElseIf searchKey < mArray(middle) Then
    
          high = middle - 1
    
     Else ' searchKey > mArray(middle)
    
          low = middle + 1
    
     End If
    
Loop
     Return IIf(found,index, -1)
End Function

=================

A Recursive Binary Search

The binary search algorithm presented above is better written as a recursive function.

Recursion is a condition in which a function or sub procedure calls itself.  

The proper definition is: a recursive call is a procedure call in which the procedure being called is the same as the one making the call.

A recursive algorithm reproduces itself with smaller and smaller instances of itself until a solution is found.  The recursive algorithm is implemented by using a procedure that makes recursive calls to itself.

A binary search requires that an array be in sorted order--either ascending or descending.

In the recursive binary search, we first compare the key with the item in the middle position of the array. If there's a match, we can return immediately. If the key is less than the middle key, then the item sought must lie in the lower half of the array; if it's greater then the item sought must lie in the upper half of the array. So we repeat the procedure on the lower (or upper) half of the array.

The binary search is recursive: it determines whether the search key lies in the lower or upper half of the array, then calls itself on the appropriate half. 

'*****************************************************************************************
'* Returns index if found, otherwise returns -1
'*****************************************************************************************
Private Function recBinarySearch ( ByVal mArray( ) As Integer, _
                                                   ByVal searchKey As Integer, _
                                                   ByVal low As Integer, _
                                                   ByVal high As Integer) As Integer
    Dim middle As Integer

    If high < low Then                             ' searchKey not in mArray
            return -1                                  ' base case #1
    Else
            middle = (low + high) \ 2
            If (searchKey = mArray(middle)) Then
                    Return  middle               ' base case #2
            ElseIf searchKey < mArray(middle) Then  
                    Return  recBinarySearch(mArray, searchKey, low, middle-1)
            Else ' searchKey > mArray(middle) 
                    Return  recBinarySearch(mArray, searchKey, middle+1, high)
            EndIf
    EndIf
End Function


VB.Net arrays now provide the Contains method to perform a linear search.