home *** CD-ROM | disk | FTP | other *** search
-
- ' SORTS.BAS
-
- ' ***************************************************
- ' * Don't forget SORTS.TXT in the global module *
- ' ***************************************************
-
- ' Being an example of an efficient in-memory sort routine.
- ' Contributed by Tom Dacon, for free.
-
- ' This algorithm implements a refinement on the bubble sort which is
- ' referred to as a comb sort. The comb sort has performance
- ' characteristics which make it nearly as fast as QuickSort with
- ' only minor modifications to the basic bubble sort algorithm.
-
- ' Ref: Byte Magazine, April 1991, "A Fast, Easy Sort",
- ' Stephen Lacey and Richard Box
-
- ' The thing that's so cool about this algorithm is that it's relatively
- ' error-free to clone the routine for different types of data elements.
-
- ' This implementation gets even faster for string sorting if you
- ' can use fixed-length strings and use the Mid$() function for
- ' swapping the contents.
-
-
- ' Depends on the following manifest constants
- ' being present in the global module.
- '
- ' Global Const FALSE, TRUE
- ' Global Const SORTASCENDING 'sort-order argument
- ' Global Const SORTDESCENDING 'sort-order argument
- ' Global Const SORTIGNORECASE 'modifier for string sorts
-
- DefInt A-Z
-
- Sub SortStrings (array() As String, ByVal firstIndex As Integer, ByVal lastIndex As Integer, ByVal sortKey As Integer)
- '
- ' Sort an array, or subset of an array,
- ' according to specified sort key.
- '
- ' Input:
- ' array() - array of elements to be sorted
- ' firstIndex - index in array() of 1st element to be sorted
- ' lastIndex - index in array() of last element to be sorted
- ' sortkey - one of SORTASCENDING or SORTDESCENDING
- ' optionally combined with SORTIGNORECASE
- ' as in (SORTASCENDING + SORTIGNORECASE)
- ' or (SORTASCENDING Or SORTIGNORECASE)
- '
-
- Const SHRINKFACTOR = 1.3 'magic number (see article)
-
- Dim gap As Integer
- Dim i As Integer
- Dim ignoreCase As Integer
- Dim j As Integer
- Dim nElements As Integer
- Dim order As Integer
- Dim swapThem As Integer 'Boolean(elements not in correct order)
- Dim switches As Integer 'Boolean(any swap occurred)
- Dim top As Integer
-
- Dim temp As String 'for the swap
-
- nElements = lastIndex - firstIndex + 1 'form count of elements to sort
-
- If nElements > 1 Then 'if there's anything to sort...
-
- ignoreCase = ((sortKey And SORTIGNORECASE) <> 0)
- order = SortAndOut(sortKey, SORTIGNORECASE)
-
- If (order = SORTASCENDING Or order = SORTDESCENDING) Then
-
- gap = nElements
- Do
- gap = Int(gap / SHRINKFACTOR)
- Select Case gap
- Case 0
- gap = 1
- Case 9, 10
- gap = 11
- Case Else
- End Select
-
- switches = FALSE
- top = lastIndex - gap
- For i = firstIndex To top
- j = i + gap
-
- Select Case order
- Case SORTASCENDING
- If ignoreCase Then
- swapThem = (UCase$(array(i)) > UCase$(array(j)))
- Else
- swapThem = (array(i) > array(j))
- End If
- Case SORTDESCENDING
- If ignoreCase Then
- swapThem = (UCase$(array(i)) < UCase$(array(j)))
- Else
- swapThem = (array(i) < array(j))
- End If
- End Select
-
- ' If they're out of order, swap them.
-
- If swapThem Then
- temp = array(i)
- array(i) = array(j)
- array(j) = temp
- switches = TRUE 'indicate we weren't done
- End If
-
- Next i
-
- Loop While switches Or (gap > 1)
-
- End If 'a valid sort order was supplied
- End If 'we have anything to sort
-
- End Sub
-
- Function SortAndOut (ByVal value1 As Integer, ByVal value2 As Integer) As Integer
- '
- ' And's out from the bits in <value1> whatever bits are set in <value2>
- ' and returns the result.
- ' For example, AndOut(&HFFFF, &H00FF) returns &HFF00.
- '
- SortAndOut = (value1 And (&HFFFF Xor value2))
-
- End Function
-
-