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
- 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.
- 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.

- 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:

- 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:

- 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:

- 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:

==================
|