'''
六、快速排序 QuickSort
介绍:
快速排序通常明显比同为Ο(n log n)的其他算法更快,因此常被采用,而且快排采用了分治法的思想,所以在很多笔试面试中能经常看到快排的影子。
可见掌握快排的重要性。
步骤:
1.从数列中挑出一个元素作为基准数。
2.分区过程,将比基准数大的放到右边,小于或等于它的数都放到左边。
3.再对左右区间递归执行第二步,直至各区间只有一个数。
(1)n大时好,快速排序比较占用内存,内存随n的增大而增大,但却是效率高不稳定的排序算法。
(2)划分之后一边是一个,一边是n-1个,这种极端情况的时间复杂度就是O(n2)
(3)最好的情况是每次都能均匀的划分序列,O(nlog2n)
(4)快速排序空间复杂度只是在通常情况下才为O(log2n),如果是最坏情况的话,很显然就要O(n)的空间了。当然,可以通过随机化选择pivot来将空间复杂度降低到O(log2n)。
'''
def quick_sort(ary):
return qsort(ary,0,len(ary)-1)
def qsort(ary,left,right):
#快排函数,ary为待排序数组,left为待排序的左边界,right为右边界
if left >= right : return ary #避免数组是0或者1位
key = ary[left] #取最左边的为基准数
lp = left #左指针
rp = right #右指针
while lp < rp :
while ary[rp] >= key and lp < rp :
rp -= 1
while ary[lp] <= key and lp < rp :
lp += 1
ary[lp],ary[rp] = ary[rp],ary[lp]
ary[left],ary[lp] = ary[lp],ary[left]
qsort(ary,left,lp-1)
qsort(ary,rp+1,right)
return ary
a = [9,3,8,5]
b = quick_sort(a, 0,len(ary)-1)
print("sequence is:", b)
方法2:
#coding:utf-8
def partion(nums,left,right):
key = nums[left]
while left < right:
# right下标位置开始,向左边遍历,查找不大于基准数的元素
while left < right and nums[right] >= key:
right -= 1
if left < right: # 找到小于准基数key的元素,然后交换nums[left],nums[right]
nums[left],nums[right] = nums[right],nums[left]
else: # left〉=right 跳出循环
break
# left下标位置开始,向右边遍历,查找不小于基准数的元素
while left < right and nums[left] < key:
left += 1
if left < right: # 找到比基准数大的元素,然后交换nums[left],nums[right]
nums[right],nums[left] = nums[left],nums[right]
else: # left〉=right 跳出循环
break
return left #此时left==right 所以返回right也是可以的
#realize from book "data struct" of author 严蔚敏
def quick_sort_standord(nums,left,right):
if left < right:
key_index = partion(nums,left,right)
quick_sort_standord(nums,left,key_index)
quick_sort_standord(nums,key_index+1,right)
if __name__ == '__main__':
nums = [5, 6, 4, 2, 3,1]
print nums
quick_sort_standord(nums,0,len(nums)-1)
print nums
方法3:
def qsort(L):
if len(L) <= 1: return L
return qsort([lt for lt in L[1:] if lt < L[0]]) + L[0:1]+ qsort([ge for ge in L[1:] if ge >= L[0]])
iList = [3,14,2,12,9,33,99,35]
print qsort(iList)
方法4:
quick_sort = lambda array: array if len(array) <= 1 else quick_sort([item for item in array[1:] if item <= array[0]]) + [array[0]] + quick_sort([item for item in array[1:] if item > array[0]])
方法5:
#QuickSort by Alvin
快速排序(quickSort)
快排的思想:首先任意选取一个数据(通常选用数组的第一个数)作为关键数据,然后将所有比它小的数都放到它前面,所有比它大的数都放到它后面,
这个过程称为一趟快速排序。
百度百科给的算法:
一趟快速排序的算法是:
1)设置两个变量i、j,排序开始的时候:i=0,j=N-1;
2)以第一个数组元素作为关键数据,赋值给key,即key=A[0];
3)从j开始向前搜索,即由后开始向前搜索(j--),找到第一个小于key的值A[j],将A[j]和A[i]互换;
4)从i开始向后搜索,即由前开始向后搜索(i++),找到第一个大于key的A[i],将A[i]和A[j]互换;
5)重复第3、4步,直到i=j; (3,4步中,没找到符合条件的值,即3中A[j]不小于key,4中A[i]不大于key的时候改变j、i的值,使得j=j-1,i=i+1,
直至找到为止。找到符合条件的值,进行交换的时候i, j指针位置不变。另外,i==j这一过程一定正好是i+或j-完成的时候,此时令循环结束)。
def QuickSort(myList,start,end):
#判断low是否小于high,如果为false,直接返回
if start < end:
i,j = start,end
#设置基准数
base = myList[i]
while i < j:
#如果列表后边的数,比基准数大或相等,则前移一位直到有比基准数小的数出现
while (i < j) and (myList[j] >= base):
j = j - 1
#如找到,则把第j个元素赋值给第个元素i,此时表中i,j个元素相等
myList[i] = myList[j]
#同样的方式比较前半区
while (i < j) and (myList[i] <= base):
i = i + 1
myList[j] = myList[i]
#做完第一轮比较之后,列表被分成了两个半区,并且i=j,需要将这个数设置回base
myList[i] = base
#递归前后半区
QuickSort(myList, start, i - 1)
QuickSort(myList, j + 1, end)
return myList
myList = [49,38,65,97,76,13,27,49]
print("Quick Sort: ")
QuickSort(myList,0,len(myList)-1)
print(myList)
方法6:
https://blog.csdn.net/razor87/article/details/71155518
方法7:
#快速排序,问题:flag是怎么从0增长到1的
def quickSort(num,l,r):
if l num[i]:
print('回车了\n')
tmp = num[i]
del num[i]
num.insert(flag,tmp) #把小数字放在大数字的地方,大数字顺便全部后移
flag+=1 #flag+1,flag以前都是排序好的。
print("flag2 is:",flag)
#print('\n')
print('num is:',num)
quickSort(num,l,flag-1) #把基准的前后部分分别排序
print("flag3 is:",flag)
quickSort(num,flag+1,r)
print("flag4 is:",flag)
return num
num = [1,9,3,8,7]
#a = quickSort(num,0,3)
#print(a)
quickSort(num,0,4)
print(num)
输出:
flag1 is: 0
num[flag] is 1
num[i] is: 9
flag1 is: 0
num[flag] is 1
num[i] is: 3
flag1 is: 0
num[flag] is 1
num[i] is: 8
flag1 is: 0
num[flag] is 1
num[i] is: 7
flag3 is: 0
flag1 is: 1
num[flag] is 9
num[i] is: 3
回车了
flag2 is: 2
num is: [1, 3, 9, 8, 7]
flag1 is: 2
num[flag] is 9
num[i] is: 8
回车了
flag2 is: 3
num is: [1, 3, 8, 9, 7]
flag1 is: 3
num[flag] is 9
num[i] is: 7
回车了
flag2 is: 4
num is: [1, 3, 8, 7, 9]
flag1 is: 1
num[flag] is 3
num[i] is: 8
flag1 is: 1
num[flag] is 3
num[i] is: 7
flag3 is: 1
flag1 is: 2
num[flag] is 8
num[i] is: 7
回车了
flag2 is: 3
num is: [1, 3, 7, 8, 9]
flag3 is: 3
flag4 is: 3
flag4 is: 1
flag3 is: 4
flag4 is: 4
flag4 is: 0
[1, 3, 7, 8, 9]
[Finished in 0.6s]