当数组具有两个值相同的实例时,Quicksort算法中的无限循环

时间:2018-12-18 00:28:36

标签: arrays vb.net sorting infinite-loop quicksort

我一直在尝试在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

1 个答案:

答案 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。可以对其进行进一步优化,以避免交换相等的元素或与自身交换元素,我会留给您