简体   繁体   English

在python中将快速排序随机化,递归问题

[英]Randomize quick sort in python, recursion issue

I am implementing randomized quick sort. 我正在实施随机快速排序。 For now I have created a function ChoosePivot(A,N) . 现在,我已经创建了一个功能ChoosePivot(A,N) This returns a random pivot and its location in input array. 这将返回随机枢轴及其在输入数组中的位置。 Then I switch that random pivot with first element in array so that pivot in Partition (A,l,r) is always first element. 然后,我用数组中的第一个元素切换该随机枢轴,以便Partition (A,l,r)中的枢轴始终是第一个元素。 For Now ChoosePivot(A,N) is also returning first element of the array but I plan to modify it later. 现在, ChoosePivot(A,N)还将返回数组的第一个元素,但我打算稍后对其进行修改。

Following is my code: 以下是我的代码:

def QuickSort(A,N):
    if (N == 1):
        return
    pivot, pivot_pos = ChoosePivot(A,N)
    l = 0
    r = len(A)
    # Preprocessing, swapping pivot position with first element so that first element remains pivot always
    temp = A[0]
    A[0] = A[pivot_pos]
    A[pivot_pos] = temp

    A, i= Partition(A,l,r)
    print A,i
    # If i-1 == 0 this means that there is no left subarray
    if (i-1 != 0):
        print "Unsorted array"
        print A[0:i-1]
        QuickSort(A[0:i-1],i-1)
        print "Left call"
        print A

    if (N-i !=0): 
        print "Unsorted array"
        print A[i:N]
        QuickSort (A[i:N], N-i)
        print "Right call"
        print A

Following is my Partition(A,l,r) 以下是我的Partition(A,l,r)

def Partition(A,l,r):
    # Now first element is the pivot
    i= l + 1
    pivot = A[l]
    for j in range(l+1, r):
        if (A[j] < pivot):
            #swap (A[j], A[i])
            temp_1 = A[i]
            A[i] = A[j]
            A[j] = temp_1
            i = i+1
    #swap (A[i-1], A[l])
    temp_2 = A[i-1]
    A[i-1] = A[l]
    A[l] = temp_2
    return A, i 

ChoosePivot(A,N) Simply returns the first element in array for now ChoosePivot(A,N)现在仅返回数组中的第一个元素

def ChoosePivot(A, N):
    #print A
    return A[0], 0

Input array I used is as follows: 我使用的输入数组如下:

Test_in = [3,8,2,5,1,4,7,6]
print Test_in

QuickSort(Test_in, len(Test_in))
print Test_in 

Please see that I can see code working at lower end of recursion. 请看到我可以看到代码在递归的低端工作。 I did dry run code with pen and paper and I can see with print statements that it does sort the sub arrays but when array is returned finally, it has not changed. 我用笔和纸进行了空运行代码,通过打印语句可以看到它确实对子数组进行了排序,但是当数组最终返回时,它并没有改变。 I thought its something related to value vs reference calling but I found that python calls by reference. 我认为它与值与引用调用有关,但是我发现python是通过引用调用的。 So there should not be any problem there. 因此,那里应该没有任何问题。 Posting output as well and pointing out exactly where it went wrong. 还要发布输出,并指出错误的确切位置。

在此处输入图片说明

I found the bug. 我发现了错误。 Problem is when I call QuickSort again, I slice the original list and pass it as argument. 问题是当我再次调用QuickSort时,我将原始列表切成薄片并将其作为参数传递。 When list is sliced python creates a new list and copied the sliced list into new list with same name. 切片列表时,python创建一个新列表,并将切片列表复制到具有相同名称的新列表中。 All changes happen in the new list deep within the recursion so they are not reflected back to the top. 所有更改都发生在递归内的新列表中,因此不会反映到顶部。 As solution I passed entire array and passed the list indices as arguments to the array. 作为解决方案,我传递了整个数组并将列表索引作为参数传递给该数组。

There was still another bug. 还有另一个错误。 Condition before calling QuickSort which is i-1!=0 and Ni!=0 are not correct as pivot could be any index in array. 调用QuickSort之前的条件i-1!=0Ni!=0不正确,因为支点可能是数组中的任何索引。 I created separate left and right indices for left and right subarray and tested left_index < right_index . 我为左右子left_index < right_index创建了单独的左右索引,并测试了left_index < right_index

Thanks 谢谢

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM