我一直在尝试在Visual Basic中编写Quicksort函数。它做起来很简单,并且对于没有两次出现相同数字的数组也很好用。但是,一旦发生这种情况,循环的第二次迭代将左指针向右指针推进,陷入了一个无穷循环,我一生都无法弄清楚为什么会发生这种情况。
如果有人知道为什么卡住了,我将不胜感激。这是代码:
Public Function Partition(ByVal a As Integer(), ByVal left As Integer, ByVal right As Integer)
Dim temp As Integer
Do While left <> right
Do While (a(left) < a(right)) And (left <> right)
left = left + 1
Loop
temp = a(left)
a(left) = a(right)
a(right) = temp
Do While (a(left) < a(right)) And (left <> right)
right = right - 1
Loop
temp = a(left)
a(left) = a(right)
a(right) = temp
Loop
Return left
End Function
Sub QuickSort(ByVal a As Integer(), ByVal left As Integer, ByVal right As
Integer)
If left < right Then
Dim position As Integer = Partition(a, left, right)
QuickSort(a, left, position - 1)
QuickSort(a, position + 1, right)
End If
End Sub
答案 0 :(得分:1)
只要a(left)
和a(right)
相同,就会发生这种情况。交换它们后,它们仍然相同,因此您一次又一次交换。
为避免这种情况,您需要
1。替换下面的循环:
Do While (a(left) < a(right)) And (left <> right)
left = left + 1
Loop
与此:
Do While (a(left) <= a(right)) And (left <> right)
left = left + 1
Loop
为了使元素等于枢轴,在其左侧
2。在第二个循环之后添加一个单步进度(但仅在迭代器没有指向暗示结束分区的相同元素的情况下):
Do While (a(left) < a(right)) And (left <> right)
right = right - 1
Loop
temp = a(left)
a(left) = a(right)
a(right) = temp
If left <> right
left = left + 1
End if
所以修改后的函数如下:
Public Function Partition(ByVal a As Integer(), ByVal left As Integer, ByVal right As Integer)
Dim temp As Integer
Do While left <> right
Do While (a(left) <= a(right)) And (left <> right)
left = left + 1
Loop
temp = a(left)
a(left) = a(right)
a(right) = temp
Do While (a(left) < a(right)) And (left <> right)
right = right - 1
Loop
temp = a(left)
a(left) = a(right)
a(right) = temp
If left <> right
left = left + 1
End if
Loop
Return left
End Function
PS。可以对其进行进一步优化,以避免交换相等的元素或与自身交换元素,我会留给您