繁体   English   中英

具有两个指针的快速排序算法

[英]Quick Sort algorithm with two pointers

你能帮我完成这个任务吗? 它来自 R。 Sedgewick 的“Introduction INTRODUCTION ТО Programming IN PYTHON Ап 跨学科方法”

分区。 编写一个 function 对已知最多有两个不同值的数组进行排序。 提示:保持两个指针,一个从左端开始向右移动,另一个从右端开始向左移动。 保持左指针左边的所有元素都等于两个值中较小的一个,而右指针右边的所有元素都等于两个值中的较大者的不变量。

所以我想出了这个,但它不起作用。 我哪里错了? 我相信这是由于两个 quickSort2 方法相互调用造成的(我在那里添加了一些评论)。

import sys      

def quickSort2(arr, left, right, n, direction):
    if n == 1:
        return
    if left > right:
        return
    if left == right:
        print ("left ")
        print([i for i in arr[len(arr)-n:left]])
        print ("right ")
        print([i for i in arr[left+1:len(arr)]])
        print ("pivot ")
        print(arr[left])

        quickSort2(arr, len(arr)-n, left-1, left-len(arr)+n, True) # Is this ok?
        quickSort2(arr, left+1, len(arr)-1, len(arr)-left-1, True) # Is this ok?

        return
    if direction:
        if arr[left] < arr[right]:
            quickSort2(arr, left+1, right, n, True)
        #elif arr[left] > arr[right]:
        else:
            arr[left], arr[right] = arr[right], arr[left]
            quickSort2(arr, left, right-1, n,  False)
    else:
        if arr[left] < arr[right]:
            quickSort2(arr, left, right-1, n,  False)
        #elif arr[left] > arr[right]:
        else:
            arr[left], arr[right] = arr[right], arr[left]
            quickSort2(arr, left+1, right, n, True)



if __name__ == "__main__":
    #array = [5,4,5,4]
    #array = [5,4,5,4,4,5,4]
    #array = [5,5,4,5,5,5,5,4,5,5,4,5,4,4,4,4,4,4,5,5,4,5,4]
    array = [5,4,4,1,7,4,3,8,3,1]

    quickSort2(array, 0, len(array) - 1, len(array),  True)
    for i in array: print (i, end = " ")

例如数组 = [5,5,4,5,5,5,5,4,5,5,4,5,4,4,4,4,4,4,5,5,4,5, 4]它返回

4 4 4 4 4 4 4 4 4 4 5 4 5 5 5 5 5 5 5 5 5 5 5

该问题不要求您实现快速排序算法,它只要求您对最多具有两个不同值的列表进行分区。 提示中的重要一点是:

保持左指针左边的所有元素都等于两个值中较小的一个,而右指针右边的所有元素都等于两个值中的较大者的不变量。

这就是您的算法无法保证的。 让我们看一下您的示例:如果左右索引都指向5并且您当前的方向是从右到左,会发生什么情况。 这个if子句将被执行:

arr[left], arr[right] = arr[right], arr[left]
quickSort2(arr, left+1, right, n, True)

因此,您交换值(没有效果,因为它们相等)并将left索引增加一。 这就是问题所在,你违反了不变量:left 指针的左边有一个5


我建议放弃direction ,因为不需要它并添加两个新变量,较小的值和较大的值。 通过这样做,您始终知道您是否可以继续前进,或者指针是否应该停留在其当前索引处。

此外,我将 function 重命名为partition ,因为这更适合练习。

def partition(arr, smaller, larger, left, right, n):
    if left >= right:
        # the two pointers met, the array is partitioned
        return
    if arr[left] == smaller:
        # move left pointer to the right
        partition(arr, smaller, larger, left+1, right, n)
    elif arr[right] == larger:
        # move right pointer to the left
        partition(arr, smaller, larger, left, right-1, n)
    else:
        # when we find a larger on the left and a smaller on the right, we swap
        arr[left], arr[right] = arr[right], arr[left]
        # and move both pointers forward
        partition(arr, smaller, larger, left+1, right-1, n)

暂无
暂无

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

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