快速排序使用分治法策略来把一个序列分为较小和较大的2个子序列,然后递归地排序两个子序列。
- 挑选基准值:从数列中挑出一个元素,称为"基准";
- 分割:重新排序数列,所有比基准值小的元素摆放在基准前面,所有比基准值大的元素摆在基准后面(与基准值相等的数可以到任何一边)。在这个分割结束之后,对基准值的排序就已经完成;
- 递归排序子序列:递归地将小于基准值元素的子序列和大于基准值元素的子序列排序。
def partition(arr,low,high):
i = low-1
cach = arr[high]
for j in range(low,high):
if arr[j] < cach:
i = i+1
arr[i],arr[j] = arr[j],arr[i]
arr[i+1],arr[high] = arr[high],arr[i+1]
print(arr)
print(i+1)
return ( i+1 )
def quicksort(arr,low,high):
if low < high:
pi = partition(arr,low,high)
quicksort(arr, low, pi-1)
quicksort(arr, pi+1, high)
m = [10,234,23,56,34,1,2,19]
n=len(m)
quicksort(m,0,n-1)
print(m)
第一步:找个基准,进入quicksort后先进行partition分割操作,返回pi值
arr[i],arr[j]发生操作的值
10 10
1 234
2 23
[10, 1, 2, 19, 34, 234, 23, 56]
返回值pi:3
第二步:进入第一个递归1.1(此时不会再进行下去,再次进入下一个递归的时候发现low < high条件不满足),退出第一个递归
arr[i],arr[j]发生操作的值
1 10
[1, 2, 10, 19, 34, 234, 23, 56]
返回值pi:1
第三步:进入第二个递归1.2,Pi是6,满足下一个递归的条件,进入以后发现传进来的是low=4<high=pi+1故满足条件进入第二个递归里面的第一个递归(可以理解他为它为2.1)
34 34
23 234
[1, 2, 10, 19, 34, 23, 56, 234]
6
第四步:进入2.1以后返回值为,再次进入递归2.2判断条件是否满足(不满足)。(此时排序也已经完成)
[1, 2, 10, 19, 23, 34, 56, 234]
4
第五步:quicksort函数全部执行完毕。
时间复杂度为O(n*log(2)n)(最坏的时候为O(n^2)) 空间复杂度O(log(2)n) 可以画一个递归树来了解(简单易懂,可以说一句那个log(2)n的意思就是有n个数,不断地除以2也就是所谓的log(2)n,和对数函数刚好相反嘛) 递归算法的时间复杂度
写给学弟们(给俺动手写,俺才懒得讲,略)
|