[英]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.