Sorting Arrays 


 

Sorting Arrays

Sorting involves arranging values in order.

Values can be compared and sorted in ascending order (smallest to largest) or descending order (largest to smallest).

There are several sorting techniques available:

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

Insertion Sort--inserting data into a sorted array

  • search array for first value which is greater than the value to be inserted.
  • shift all values from the greater one on down to make room for the new value
  • makes the list grow by one with each insertion
  • the following example assumes that the array is dynamic or has unused elements

Call insertionSort(numberList, 12)

Private Sub insertionSort(ByRef targetArray() As Integer, _
                                    ByVal insertedNum As Integer)
     Dim looking As Boolean = True
     Dim ptr As Integer = 0
     Dim arrayBound As Integer = targetArray.GetUpperBound(0)
     Dim lcv As Integer

     If arrayBound = 0 Then
          ' insert first item
          targetArray(ptr) = insertedNum
     Else ' search for insertion point
          While looking And (ptr <= arrayBound)
               If targetArray(ptr) > insertedNum Then
                    looking = False
               Else
                    ptr = ptr + 1
               End If
          End While

          ReDim Preserve targetArray(arrayBound + 1)
          ' shift upper values
          For lcv = arrayBound To ptr Step -1
               targetArray(lcv + 1) = targetArray(lcv)
          Next lcv

          ' insert value
          targetArray(ptr) = insertedNum
     End If
End Sub

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

Sorting an unsorted array is a common problem.

  • Bubblesort -- slowest but simple
  • Selection Sort -- also pretty slow
  • Quicksort -- Fast but complex, best using recursion

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

Bubblesort

Technique

  • compare value 1 with value 2
  • if value 2 is smaller, switch 1 and 2
  • compare value 2 with value 3
  • if value 3 is smaller, switch 3 and 2
  • compare value 3 with value 4
  • etc.

Private Sub bubbleSort(ByVal List( ) As Integer)
     Dim i As Integer, j As Integer
     Dim lowerIndex As Integer, upperIndex As Integer

     lowerIndex = 0
     upperIndex = List.GetUpperBound(0)

     For i = lowerIndex To upperIndex - 1
          For j = lowerIndex To upperIndex - 1 
               If (List(j) > List(j + 1)) Then
                    Call Swap(List(j), List(j + 1))
               End If
          Next j
     Next i
End Sub

'============================================

Private Sub swap ( ByRef one As Integer, ByRef two As Integer )
      Dim temp As Integer

      temp = one
      one = two
      two = temp
End Sub

 

If the loop varied from 1 to List.GetUpperBound(0), the code would try to access List(List.GetUpperBound(0)+ 1), which would cause an index out of range exception.

See additional information on an improved bubble sort.

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

Selection Sort

Technique

  • scan the array
  • find the smallest value and store it in location 1
  • scan the array
  • find the 2nd smallest value and store it in location 2
  • etc.

Private Sub selectionSort ( ByVal List( ) As Integer )
     Dim i As Integer, j As Integer, lowerIndex As Integer, upperIndex As Integer
     Dim holdIndex As Integer, holdElement As Integer

     lowerIndex = 0
     upperIndex = List.GetUpperBound(0)

     For i = lowerIndex To upperIndex - 1
          holdIndex = i
          holdElement = List(i)
          For j = i + 1 To upperIndex 
               If (List(j) < holdElement) Then
                    holdIndex = j
                    holdElement = List(j)
               End If
          Next j
          List(holdIndex) = List(i)
          List(i) = holdElement
     Next i
End Sub

For a modularized (and perhaps clearer) version of the Selection Sort, click here.

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

Quicksort

Quicksort is a fast and efficient sorting algorithm. It has two phases:

  • the partition phase  
  • the sort (recursive) phase 

Most of the work is done in the partition phase - the phase in which it determines where to divide the work.  The sort phase simply sorts the two smaller problems that are generated in the partition phase. 

Quicksort is another good example of the divide and conquer strategy for solving problems, similar in approach to the binary search.  In quicksort,  the array of items to be sorted is divided into two partitions and then the quicksort procedure is called recursively to sort the two partitions, i.e., the problem is divided into two smaller ones and conquered by solving the smaller ones.

The partition phase must ensure that all the items in the lower part are smaller than all those in the upper part.  To do this, choose a pivot element and arrange the array so that all the items in the lower part are less than the pivot and all those in the upper part are greater than the pivot.  Since little is known about the items to be sorted, any choice of the pivot element will do.  For that reason the first element can be arbitrarily chosen as the pivot.

The general algorithm states

  1. Partition phase: take the first element of the unsorted array and determine its final location in the sorted array.  In other words, the array must be arranged so that all values to the left of the element in the array are less than the element, and all values to the right of the element in the array are greater than the element.  The result is one element in its proper location and two unsorted subarrays.
  2. Recursive phase: perform step 1 on each unsorted subarray.

Each time step 1 is performed on a subarray, another element is placed in its final location of the sorted array, and two unsorted subarrays are created.  When a subarray consists of one element, it must be sorted; therefore that element is in its final location.

The following example shows how the partitioning element is placed in its proper location.  The first element will be arbitrarily selected as the pivot element.

  1. Starting from the rightmost element of the array, compare each element to 37 until an element less than 37 is found, then swap 37 and that element.  The first element less than 37 is 12, so 37 and 12 are swapped.  The new array is:

  1. Starting from the left of the array, but beginning with the element after 12, compare each element to 37 until an element greater than 37 is found, then swap 37 and that element.  The first element greater than 37 is 89, so 37 and 89 are swapped.  The new array is:

  1. Starting from the right, but beginning with the element before 89, compare each element to 37 until an element less than 37 is found, then swap 37 and that element.  The first element less than 37 is 10 so 37 and 10 are swapped.  The new array is:

  1. Starting  from the left, but beginning with the element after 10, compare each element to 37 until an element greater than 37 is found, and then swap 37 and that element.  There are no more element greater than 37, so when we compare 37 to itself we know that 37 has been placed in its correct location in the sorted array.  The partitioned array is:

 

Once the first partition has been completed, there are two unsorted subarrays.   The sort will continue with both subarrays being partitioned in the same manner as the original array.

______________________

As noted above, since little is known about the items to be sorted, any choice of the pivot element will do, and many implementations arbitrarily choose the first element as the pivot.  However, if the array is already sorted, or if the pivot element happens to be the largest or smallest value in the array, then while the sort will work correctly, it will not be particularly quick, due to the lopsided splits.  (In the case of the sorted array, one segment will contain one element, and the other will contain the remaining elements.)  For this reason, the middle element in the array is often selected as the pivot.

Private Sub quicksort ( ByVal data( ) As Integer, _
                                  ByVal low As Integer, _
                                  ByVal high As Integer )

      Dim pivot As Integer
      ' Termination condition!
      If (high > low) Then
            pivot = partition(data, low, high)
            Call quicksort(data, low, pivot - 1)
            Call quicksort(data, pivot + 1, high)
      End If
End Sub


'============================================

Private Function partition ( ByVal data( ) As Integer,  _
                                       ByVal low As Integer, _
                                       ByVal high As Integer ) As Integer

      Dim left As Integer, right As Integer
      Dim pivot_item As Integer
      Dim pivot As Integer

      pivot = (low + high) \ 2
      pivot_item = data(pivot)
      left = low
      right = high

      While (left < right)
            ' Move left while item < pivot
            While data(left) < pivot_item
                  left = left + 1
            End While

            ' Move right while item > pivot
            While data(right) > pivot_item
                  right = right - 1
            End While

            If (left < right) Then
                  Call swap(data(left), data(right))
            End If
      End While

      partition = right

End Function

'============================================

Private Sub swap ( ByRef one As Integer, ByRef two As Integer )
      Dim temp As Integer

      temp = one
      one = two
      two = temp
End Sub

 

Original array:

After swap 1:

After swap 2:

Final array with subarrays highlighted:

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

Click here for an on-line 
animated demo of sorting algorithms.
  And another!


To make life easier, VB.Net arrays now provide the Sort method.  For a tutorial visit this link.