#双指针 快速排序 O(nlogn)
def quickSort(listA,start,end):
if(listA == None or len(listA) == 0):
return -1
#递归出口:
if(start >= end):
return -1
left = start
right = end
pivotValue = listA[(start+end)//2]
while(left<=right):
#listA[left]<pivotValue
# not listA[left]<=pivotValue
#保证最后双指针相遇的地方
#左右两边元素个数大致相等
#logn
while(left<=right and listA[left]<pivotValue):
#listA[left]<pivotValue
#left停到大于等于 pivotValue处,再交换,移动
#left<=right
#此内层循环left最多停到right+1处
left+=1
while(left<=right and listA[right]>pivotValue):
#listA[right]>pivotValue
#right停到小于等于pivotValue处,再交换移动
#left<=right
#此内层循环right最多停到left-1处
right-=1
#left<=right 交换,向右移动left,向左移动right
#没有等于,则会导致递归无限死循环
#(手动尝试两个不一样数字,体验递归死循环,找不到递归出口)
#所以:left right 相等时,必须更新
#准确来说,两个指针的相遇有九种情况+1:
# left right
# < <
# < =
# < >
# left right
# = <
# = =
# = >
# left right
# > <
# > =
# > >
#还有指向同一元素情况(在交换移动后指向同一个元素)
#解决复杂排序问题:
#1. 列出各种情况
#2. 分情况讨论
#3. 将各种情况归纳总结
#另一种标准分类:(宏观上把握)
# left<=right 可以保证left right 差值 <=1
# ^ ^ #
# left right #
# <= # >= <= # >=
# ^ #
# left right #
# <= # = = # >=
# ^ ^ #
# right left #
# <= # <= >= # >=
#交换完成最终:
#1. right = left + 1
#2. right = left + 2(中间元素=pivotValue)
if(left<=right):
listA[left],listA[right] = listA[right],listA[left]
left+=1
right-=1
#right右边全部比 pivotValue 大,且right指向<=
quickSort(listA,start,right)
#left 左边全部比 pivotValue小,且left指向>=
quickSort(listA,left,end)
list1 = [5,7,3,6,5,4,9,8,0,2,1]
quickSort(list1,0,10)
print(list1)
[0, 1, 2, 3, 4, 5, 5, 6, 7, 8, 9]