Simple Ascend Sorting

in Visual Basic®

by Rick Meyer       Home

Other Sorting Pages
Simple Descend Sorting
Simple Bi-Direction Sorting
Sorting Viewer
Sorting Timer

Below you will find simplified procedures for sorting in ascending order with:
  • Bubble Sort
  • BiBubble Sort
  • Insertion Sort
  • Shell Sort
  • Selection Sort
  • BiSelection Sort
  • Quick Sort
  • Heap Sort
  • These procedures have been incorporated into a project so that you can watch and experiment with them. Use the following instructions to construct the project or just copy the specific procedures that you want.
      Instructions for Building this Project:

    1. Start a new standard exe.
    2. On Form1 put a CommandButton named Command1.
    3. On Form1 put a CommandButton named Command2.
    4. Set the Command1.Index property to 0.
    5. Vary the MIN and MAX constants as desired.

    There is no need to position or size the above controls
    on the form since that is all done in the Form_Load.

    Now you are ready for the code. Select all of the following code (by clicking on the word 'Option' three times) and copy it to the clipboard [Ctrl][Insert]. Then paste it into the code window of Form1 with [Shift][Insert]. Variable Key
    % As Integer
    & As Long
    ! As Single
    # As Double
    $ As String
    Option Explicit
    
    Const MIN = 1, MAX = 12
    
    Private Enum sortType
        BUBBLE
        BIBUBBLE
        INSERTION
        SHELLS
        SELECTION
        BISELECTION
        QUICK
        HEAP
    End Enum
    
    Dim Last1%
    Dim sortarray() As Integer
    
    '======================================================
    ' The classic Bubble Sort is about the simplest in that
    '   it just makes continual passes on an array
    '   swapping an element with the one above it until on
    '   one pass there are no swaps made so it knows its
    '   work is done.
    '======================================================
    Private Sub Bubble_Sort()
        Dim j%, last%, tmp%, Done As Boolean
        
        'End the loop 1 less than Last1
        ' because we are comparing with j + 1
        last = Last1 - 1
        
        Do While Not Done
            Done = True 'Set the boolean optimisticly
            
            For j = 0 To last
                If sortarray(j) > sortarray(j + 1) Then
                    'The swap
                    tmp = sortarray(j)
                    sortarray(j) = sortarray(j + 1)
                    sortarray(j + 1) = tmp
                    
                    'If we have made one swap then we are not done
                    ' and we must make another full pass
                    Done = False
                End If
            Next
            
            'At the end of one pass the highest element is
            ' bubbled up to the top - so wee don't need to
            ' compare it again
            last = last - 1
        Loop
    End Sub
    
    '======================================================
    ' A BiBubble Sort first bubbles the largest item to
    '   the top just like the bubble sort, but then
    '   it next bubbles the smallest item down to
    '   the bottom.
    '======================================================
    Private Sub BiBubble_Sort()
        Dim j%, first%, last%, tmp%, Done As Boolean
            
        last = Last1 - 1
        Do While Not Done
            Done = True
            For j = first To last
                If sortarray(j) > sortarray(j + 1) Then
                    tmp = sortarray(j)
                    sortarray(j) = sortarray(j + 1)
                    sortarray(j + 1) = tmp
                    Done = False
                End If
            Next
            
            If Done Then Exit Do
            first = first + 1
            
            'Now we bubble down from the top
            For j = last To first Step -1
                If sortarray(j) < sortarray(j - 1) Then
                    tmp = sortarray(j)
                    sortarray(j) = sortarray(j - 1)
                    sortarray(j - 1) = tmp
                    Done = False
                End If
            Next
            
            last = last - 1
        Loop
    End Sub
    
    '======================================================
    ' The Insertion Sort is kind of a reverse bubble where
    '   elements are examined from low to high but the
    '   values are compared with the element below and
    '   swapped down to its lowest possible position. It
    '   ends up being about as efficient as the bubble sort
    '   since effectively there is one pass for each
    '   element.
    '======================================================
    Private Sub Insertion_Sort()
        Dim j%, low%, high%, tmp%
        
        For j = 1 To Last1
            high = j
            Do
                low = high - 1
                If sortarray(low) > sortarray(high) Then
                    tmp = sortarray(low)
                    sortarray(low) = sortarray(high)
                    sortarray(high) = tmp
                    
                    'Since a swap has been made we try
                    ' to take the swapped element lower.
                    high = low  'same as high = high - 1
                Else
                    'When there are no more swaps then
                    ' this element has been taken as low
                    ' as it will go
                    Exit Do
                End If
            Loop Until high <= 0
        Next
    End Sub
    
    '======================================================
    'Another version of the Insertion Sort (no button)
    '  demonstrating the shuffle up assignment rather
    '  than swapping each element with the next 1. This
    '  can save approx 66% of swapping assignments in
    '  a large array.
    '======================================================
    Private Sub Insertion_Shuffle_Sort()
        Dim j%, low%, high%, tmp%
        
        For j = 1 To Last1
            high = j
            tmp = sortarray(high)
    
            Do
                low = high - 1
                If sortarray(low) <= tmp Then Exit Do
                sortarray(high) = sortarray(low)
                high = low
            Loop Until high <= 0
    
            sortarray(high) = tmp
        Next
    End Sub
    
    '======================================================
    ' The Shell Sort is an insertion sort that compares
    '   elements that are more than 1 apart.
    ' The diff (or offset determines how far apart the
    '   compared (and swapped) items will be. After
    '   each pass the diff becomes progressively smaller
    '   until it is 1 - and then finally 0.
    ' Swapping elements far apart can result in
    '   considerable time saving.
    '======================================================
    Private Sub Shell_Sort()
        Dim diff%, low%, high%, tmp%
        
        'The classic divisor to obtain the offset is 2
        'Note: diff = (MAX - MIN) \ 2
        diff = Last1 \ 2
        
        Do While diff
            'Establish starting high position
            'Note: high = MIN + diff
            high = diff
            
            Do Until high > Last1
                'Compute the low position
                low = high - diff
                
                If sortarray(low) > sortarray(high) Then
                    tmp = sortarray(low)
                    sortarray(low) = sortarray(high)
                    sortarray(high) = tmp
                    
                    'If a swap is made then we chase
                    ' it down like an insertion sort.
                    ' This guarantees that eventually
                    ' when diff = 1 then the array will
                    ' be fully sorted.
                    If diff = 1 Then
                        'Chase lower only on final pass
                        ' (Insertion Sort)
                        If low > 0 Then high = low - 1
                        'Made 1 less because incr below
                    End If
                End If
                
                high = high + 1
            Loop
            
            'You can experiment with other divisors
            ' (like 1.3 here) to improve speed
            ' taking care that eventually diff
            ' will become 1 and 0. When it becomes 0
            ' we pop out of the loop
            diff = Int(CSng(diff) / 1.3)
        Loop
    End Sub
    
    '======================================================
    ' The Selection Sort simply makes progressive passes to
    '   find the smallest element. It then swaps that
    '   element into the lowest position and subsequent
    '   passes do not examine the placed element.
    '======================================================
    Private Sub Selection_Sort()
        Dim j%, low%, lower%, tmp%
        
        Do Until lower >= Last1
            'First assume the lowest position
            '  is the low value.
            low = lower
                    
            'Run through the remaining elements
            '  keep track of the low value
            For j = lower + 1 To Last1
                If sortarray(j) < sortarray(low) Then low = j
            Next
            
            'Now swap if it is not positioned correctly
            If low <> lower Then
                tmp = sortarray(lower)
                sortarray(lower) = sortarray(low)
                sortarray(low) = tmp
            End If
            
            'Increment so we don't examine
            '  this position again
            lower = lower + 1
        Loop
    End Sub
    
    '======================================================
    ' The BiSelection Sort is like the Selection Sort but
    '   keeps track of both the lowest and the highest
    '   value on a single pass. At the end of the pass
    '   the highest value found is swapped to the highest
    '   position and the lowest valuefound is swapped to
    '   the lowest position.
    '======================================================
    Private Sub BiSelection_Sort()
        Dim j%, low%, high%, lower%, upper%, tmp%
        
        upper = Last1
        
        Do Until lower >= upper
            'Initialize with elements at the ends
            high = upper
            low = lower
                    
            'Loop to find highest and lowest value
            For j = lower To upper
                If sortarray(j) < sortarray(low) Then
                    low = j
                ElseIf sortarray(j) > sortarray(high) Then
                    high = j
                End If
            Next
            
            'Swap the highest found to highest position
            If high <> upper Then
                If low = upper Then low = high
                tmp = sortarray(upper)
                sortarray(upper) = sortarray(high)
                sortarray(high) = tmp
            End If
            
            'Swap the lowest found to lowest position
            If low <> lower Then
                tmp = sortarray(lower)
                sortarray(lower) = sortarray(low)
                sortarray(low) = tmp
            End If
            
            'Move the ends in towards the center
            lower = lower + 1
            upper = upper - 1
        Loop
    End Sub
    
    '======================================================
    ' The Quick Sort is so named because of its ability to
    '   sort extremely fast by swapping elements that may
    '   be a great many positions apart. It starts by
    '   choosing a mid value around which to base its
    '   swaps in the middle of the array. Since the center
    '   position actually may hold a value that is far from
    '   an optimal mid value, some have attempted to
    '   improve this technique of selecting a mid value.
    ' Perhaps the most interesting part of this sort is
    '   that the procedure is recursive. You will note at
    '   the end of the procedure are 2 lines that call
    '   itself (the two halves of the array that do not
    '   get sorted by the original call).
    ' This recursive feature has the price of using
    '   increasing stack space to store the dimmed
    '   variables which in very large arrays may have the
    '   penalty of blowing the STACK space where these temp
    '   variables are stored in memory. Since this can have
    '   the effect of crashing your program, most sorting
    '   done nowadays implements a Heap Sort.
    '======================================================
    Private Sub Quick_Sort(ByVal lower%, ByVal upper%)
        If lower >= upper Then Exit Sub
        
        Dim low%, midl%, high%, midval%, tmp%
        
        low = lower
        high = upper
        
        'Determine a mid value by position only
        midl = (lower + upper) \ 2
        midval = sortarray(midl)
     
        Do While low <= high
            'Find a value higher than the mid value
            '  that is below the midpoint
            Do Until low >= upper
                If sortarray(low) >= midval Then Exit Do
                low = low + 1
            Loop
         
            'Find a value lower than the mid value
            '  that is above the midpoint
            Do Until high <= lower
                If midval >= sortarray(high) Then Exit Do
                high = high - 1
            Loop
     
            If low <= high Then
                'Note we do not want to increment low and
                '  decrement high if they have collided
                If low < high Then
                    'This test means we have found:
                    '1. A value higher than midval
                    '2. A value lower than midval
                    '3. They are out of order
                    '(if one or the other has not been
                    ' found then low will be >= high)
                    tmp = sortarray(low)
                    sortarray(low) = sortarray(high)
                    sortarray(high) = tmp
                End If
                low = low + 1
                high = high - 1
                'We continue until high and low collide
            End If
        Loop
    
        'These are the recursive calls designed to sort
        ' two halves after high and low have collided
        If lower < high Then Quick_Sort lower, high
        If low < upper Then Quick_Sort low, upper
    End Sub
    
    '======================================================
    ' Discussions of the Heap Sort revolve around nodes
    '   and sifting. The method defies simple explanation.
    '======================================================
    Private Sub Heap_Sort()
        Dim j%, tmp%
    
        'Note: j = MAX - (MAX - MIN) \ 2
        j = Last1 - Last1 \ 2
        
        Do Until j >= Last1
            SiftUp Last1, j, 0
            j = j + 1
        Loop
    
        For j = 0 To Last1 - 1
            If sortarray(Last1) < sortarray(j) Then
                tmp = sortarray(Last1)
                sortarray(Last1) = sortarray(j)
                sortarray(j) = tmp
                
                SiftUp Last1, Last1 - 1, j
            End If
        Next
    End Sub
    Private Sub SiftUp(first%, ByVal midl%, last%)
        Dim k%, k1%, m1%, tmp%
        
        k = (midl - first) * 2 + first
        Do While k >= last
            If k > last Then
                k1 = k + 1
                If sortarray(k) < sortarray(k1) Then
                    k = k - 1
                End If
            End If
            
            k1 = k + 1
            m1 = midl + 1
            
            If sortarray(k1) < sortarray(m1) Then
                tmp = sortarray(k1)
                sortarray(k1) = sortarray(m1)
                sortarray(m1) = tmp
            Else
                Exit Do
            End If
            midl = k
            k = (midl - first) * 2 + first
        Loop
    End Sub
    
    Private Sub Command1_Click(Index As Integer)
        Caption = Command1(Index).Caption
        
        Select Case Index
            Case BUBBLE: Bubble_Sort
            Case BIBUBBLE: BiBubble_Sort
            Case SHELLS: Shell_Sort
            Case INSERTION: Insertion_Sort
            Case SELECTION: Selection_Sort
            Case BISELECTION: BiSelection_Sort
            Case QUICK: Quick_Sort 0, Last1
            Case HEAP: Heap_Sort
        End Select
        
        ShowArray
    End Sub
    
    'Randomize the Array
    Private Sub Command2_Click()
        Dim j%, k%
        Dim c As New Collection
        
        Randomize
        Last1 = MAX - MIN
        ReDim sortarray(Last1)
        
        For j = MIN To MAX
            c.Add j
        Next
        
        Do While c.Count > 0
            j = Int(c.Count * Rnd) + 1
            sortarray(k) = CInt(c.Item(j))
            c.Remove j
            k = k + 1
        Loop
        
        Caption = "Ascend Sorting"
        ShowArray
    End Sub
    
    Private Sub ShowArray()
        Dim j%
        
        Cls
        For j = 0 To Last1
             Print sortarray(j)
        Next
    End Sub
    
    Private Sub Form_Load()
        Const MARGIN = 200, HGHT = 300, WDTH = 1600
        Dim j%, lt!, tp!
        
        Move 1000, 1000, 4800, 3600
        tp = MARGIN
        lt = Width - (WDTH + MARGIN) * 2
        
        For j = 0 To 7
            If j Then Load Command1(j)
            
            With Command1(j)
                .Move lt, tp, WDTH, HGHT
                .FontBold = True
                Select Case j
                    Case BUBBLE: .Caption = "Bubble Sort"
                    Case BIBUBBLE: .Caption = "BiBubble Sort"
                    Case INSERTION: .Caption = "Insertion Sort"
                    Case SHELLS: .Caption = "Shell Sort"
                    Case SELECTION: .Caption = "Selection Sort"
                    Case BISELECTION: .Caption = "BiSelection Sort"
                    Case QUICK: .Caption = "Quick Sort"
                    Case HEAP: .Caption = "Heap Sort"
                End Select
                .Visible = True
            End With
            
            If j = 3 Then
                lt = lt + MARGIN + WDTH
                tp = MARGIN
            Else
                tp = tp + HGHT + MARGIN
            End If
        Next
        
        lt = lt - MARGIN - WDTH
        With Command2
            .Move lt, tp, WDTH * 2 + MARGIN, HGHT
            .FontBold = True
            .Caption = "Randomize"
        End With
            
        AutoRedraw = True
        FontBold = True
        Command2_Click
    End Sub