1、快速排序
快速排序算法,简称快排,是最实用的排序算法,没有之一,各大语言标准库的排序函数也基本都是基于快排实现的。
用递归思路:
思想:随机选取一个基准,通常可以是第一个数或者最后一个数。
将剩下的数分为两个数组,小于等于这个数的划分到左数组,大于这个数划分到右数组。然后返回 左数组+基准+右数组。接着递归进去,对左、右数组做同样的操作,也就是做快排。直到子数组的长度小于等于1时,返回单独的数或者空,结束递归。
# 实现快排
def quicksort(qlist):
if(len(qlist) <= 1):
return qlist
# 左子数组
left = []
# 右子数组
right = []
# 基准数
base = qlist.pop()
# 对原数组进行划分
for i in qlist:
if(i<base):
left.append(i)
else:
right.append(i)
# 递归调用
return quicksort(left) + [base] + quicksort(right)
if __name__=='__main__':
nums = [6,1,2,7,9,3,4,5,10,8]
print(quicksort(nums))
num=input().split(' ')
print(quicksort(num))
另一个递归思路:
选取一个基准数,比如第一个数。
设置left和right两个指针,初始值left指向数组开端,right指向数组末端。如果left < right则开始大循环,设置第一个子循环里right指针从数组末端向前扫描,如果指针的数比基准大就继续向前,一旦right的指针数比基准小,则跳出循环停止扫描,将当前值赋给left指针指向的值。设置第二个子循环left从数组开始向末端扫描,如果指针当前值比基准小,则继续扫描,一旦数比基准大,停止扫描,并将当前的值赋给right指针指向的值。继续开始下一次大循环,直到left和right相等,停止循环。
循环结束后,将基准值(最开始left指针指向的值)赋值给当前right指针指向的值。
这样一趟完成了右边比base小的数和左边比base大的数的交换,交换完了,比base小的数就放在base左边,大的数放base右边。
于是开始对base左边的数组递归快排,对base右边的数组递归快排。
直到递归结束,排完数组。
# 实现快排
def quick_sort(array, left, right):
if(left >= right):
return
low = left
high = right
key = array[low]#存储一开始最左端的值,待会交换到最后,要把值赋给右指针
while(left < right):
while(left < right and array[right] > key):
right =right - 1
array[left] = array[right]
while(left < right and array[left] <= key):
left = left + 1
array[right] = array[left]
array[right] = key
quick_sort(array, low, left - 1)
quick_sort(array, right + 1, high)
if __name__=='__main__':
nums = [6,1,2,7,9,3,4,5,10,8]
quick_sort(nums,0,len(nums)-1)
print(nums)
各种常用排序算法 |
||||||||
类别 |
排序方法 |
时间复杂度 |
空间复杂度 |
稳定性 |
复杂性 |
特点 |
||
最好
扫描二维码关注公众号,回复:
3092211 查看本文章
|
平均 |
最坏 |
辅助存储 |
|
简单 |
|
||
插入 排序 |
直接插入 |
O(N) |
O(N2) |
O(N2) |
O(1) |
稳定 |
简单 |
|
希尔排序 |
O(N) |
O(N1.3) |
O(N2) |
O(1) |
不稳定 |
复杂 |
|
|
选择 排序 |
直接选择 |
O(N) |
O(N2) |
O(N2) |
O(1) |
不稳定 |
|
|
堆排序 |
O(N*log2N) |
O(N*log2N) |
O(N*log2N) |
O(1) |
不稳定 |
复杂 |
|
|
交换 排序 |
冒泡排序 |
O(N) |
O(N2) |
O(N2) |
O(1) |
稳定 |
简单 |
1、冒泡排序是一种用时间换空间的排序方法,n小时好 |
快速排序 |
O(N*log2N) |
O(N*log2N) |
O(N2) |
O(log2n)~O(n) |
不稳定 |
复杂 |
1、n大时好,快速排序比较占用内存,内存随n的增大而增大,但却是效率高不稳定的排序算法。 |
|
归并排序 |
O(N*log2N) |
O(N*log2N) |
O(N*log2N) |
O(n) |
稳定 |
复杂 |
1、n大时好,归并比较占用内存,内存随n的增大而增大,但却是效率高且稳定的排序算法。 |
|
基数排序 |
O(d(r+n)) |
O(d(r+n)) |
O(d(r+n)) |
O(rd+n) |
稳定 |
复杂 |
|
|
注:r代表关键字基数,d代表长度,n代表关键字个数 |