如何通过VBA中的属性快速排序对象数组?

时间:2014-06-07 19:07:36

标签: vba quicksort

在尝试按属性对对象进行排序时,我无法在快速排序算法中使用VBA。 bubbleort工作正常。我认为这与对象引用有关,但我似乎无法做到正确。 Bubblesort曾经也失败了,直到我向我的对象添加了一个克隆方法。

以下是相关支持代码的代码:http://pastebin.com/egcph0jJ

这是相关功能:

Private Sub quick_sort_file_array_by_modified(file_array As Variant,inLowBound As Long,inHighBound As Long)

  'Do a quicksort on date_modified

  Dim pivot   As ParsedFile
  Dim tmpSwap As ParsedFile
  Dim tmpLow  As Long
  Dim tmpHi   As Long

  tmpLow = inLowBound
  tmpHi = inHighBound

  Set pivot = file_array((inLowBound + inHighBound) / 2)

  While (tmpLow <= tmpHi)

    Dim tmp_low_file As ParsedFile
    Set tmp_low_file = file_array(tmpLow)

     While (tmp_low_file.file_mod_date < pivot.file_mod_date And tmpLow < inHighBound)
        tmpLow = tmpLow + 1
     Wend

     Dim tmp_high_file As ParsedFile
     Set tmp_high_file = file_array(tmpHi)

     While (pivot.file_mod_date < tmp_high_file.file_mod_date And tmpHi > inLowBound)
        tmpHi = tmpHi - 1
     Wend

     If (tmpLow <= tmpHi) Then
        Set tmpSwap = file_array(tmpLow)
        Set file_array(tmpLow) = file_array(tmpHi).clone
        Set file_array(tmpHi) = tmpSwap.clone
        tmpLow = tmpLow + 1
        tmpHi = tmpHi - 1
     End If

  Wend

  If (inLowBound < tmpHi) Then quick_sort_file_array_by_modified file_array, inLowBound, tmpHi
  If (tmpLow < inHighBound) Then quick_sort_file_array_by_modified file_array, tmpLow, inHighBound


End Sub

...结果是它根本没有真正改变对象数组的顺序。

1 个答案:

答案 0 :(得分:1)

您的快速排序算法错误。

While (tmp_low_file.file_mod_date < pivot.file_mod_date And tmpLow < inHighBound)
        tmpLow = tmpLow + 1
Wend

您只更新索引计数器,但不更新比较值 “tmp_low_file.file_mod_date&lt; pivot.file_mod_date”总是保持不变,而你tmpLow将 直到inHighBound。

运行此测试代码,您将看到哪里出错。

Public Sub test()
    changedArr = Array(2, 1, 33, 89, 76, 10, 11)
    quick_sort_file_array_by_modified changedArr, 0, 6
End Sub

Private Sub quick_sort_file_array_by_modified(file_array As Variant, inLowBound As Long, inHighBound As Long)

    'Do a quicksort on date_modified

      Dim pivot   As Integer
      Dim tmpSwap As Integer
      Dim tmpLow  As Long
      Dim tmpHi   As Long
      Debug.Print "inLowBound: "; CStr(inLowBound) & "  inHighBound:" & CStr(inHighBound)
      PrintArr file_array
      tmpLow = inLowBound
      tmpHi = inHighBound

      pivot = file_array((inLowBound + inHighBound) / 2)

      Debug.Print "Pivot Value:" & pivot

      While (tmpLow <= tmpHi)

        Dim tmp_low_file As Integer
        tmp_low_file = file_array(tmpLow)

         While (tmp_low_file < pivot And tmpLow < inHighBound)
            tmpLow = tmpLow + 1
         Wend



         Dim tmp_high_file As Integer
         tmp_high_file = file_array(tmpHi)

         While (pivot < tmp_high_file And tmpHi > inLowBound)
            tmpHi = tmpHi - 1
         Wend

         If (tmpLow <= tmpHi) Then

            Debug.Print "Swaping: " & CStr(tmpLow) & " to "; CStr(tmpHi)

            tmpSwap = file_array(tmpLow)
            file_array(tmpLow) = file_array(tmpHi)
            file_array(tmpHi) = tmpSwap
            tmpLow = tmpLow + 1
            tmpHi = tmpHi - 1
         End If
         PrintArr file_array
      Wend

      Debug.Print "inLowBound: "; CStr(inLowBound) & "  tmpHi:" & CStr(tmpHi)
      Debug.Print "tmpLow: "; CStr(tmpLow) & "  inHighBound:" & CStr(inHighBound)

      If (inLowBound < tmpHi) Then
        Debug.Print "calling case inLowBound < tmpHi"
        Debug.Print "---------------------------------"
        quick_sort_file_array_by_modified file_array, inLowBound, tmpHi
      End If

      If (tmpLow < inHighBound) Then
        Debug.Print "calling case tmpLow < inHighBound"
        Debug.Print "---------------------------------"
        quick_sort_file_array_by_modified file_array, tmpLow, inHighBound
      End If

End Sub


Private Sub PrintArr(arr As Variant)
    Dim a As Variant
    Dim result As String
    For Each a In arr
        result = result & CStr(a) & "  "
    Next
    Debug.Print result
End Sub