快速排序-总结与改进
2017-03-23 12:04
197 查看
之前的几次面试都有问到快速排序,我的写法都是按照算法导论上随便写写的:
考虑从两端划分:
i从左往右扫,j从右往左扫;
如果i>=j循环终止
否则交换i,j对应的值(这里相当于又找到了一个大于等于key和一个小于等于key的数,i++,j–)
(python没有do while 写成这个会比较简单)
所以应该选择随机选择划分元素.
在 if的后面加上:
快速排序花费了大量的时间来排序很小的子数组,如果采用插入排序会更快
可以修改为:
其中,cutoff是一个小整数,然后选择其他排序算法进行排序。
一:基本快速排序:(参照算法导论)
#快速排序 def quicksort(nums,p,r): if p<r: q=partition(nums,p,r) quicksort(nums,p,q-1) quicksort(nums,q+1,r) return def partition(nums,p,r): x=nums[r] i=p-1 #记录位置 for j in range(p,r): if nums[j]<=x: i+=1 nums[i],nums[j]=nums[j],nums[i] nums[i+1], nums[r] = nums[r], nums[i+1] return i+1
二:偶尔会问怎么改成非递归的
def quicksort2(nums,p,r): #非递归实现,只需要申请一个 栈来记录 需要排序的起始位置与终点位置 stack=[p,r] while stack: new_r=stack.pop() new_p=stack.pop() q=partition(nums,new_p,new_r) if new_p<q-1: stack.extend([new_p,q-1]) if new_r>q+1: stack.extend([q+1,new_r]) return nums
三:写成一个函数
def quicksort(nums,p,r): if p>=r:return x=nums[r] i=p-1 #记录位置 for j in range(p,r): if nums[j]<=x: i+=1 nums[i],nums[j]=nums[j],nums[i] nums[i+1], nums[r] = nums[r], nums[i+1] q=i+1 quicksort(nums,p,q-1) quicksort(nums,q+1,r) return
四:如果从前端取值:
def quicksort(nums,p,r): if p>=r:return x=nums[p] i=p #记录位置 for j in range(p+1,r+1): if nums[j]<x: i+=1 nums[i],nums[j]=nums[j],nums[i] #最后的结果:nums[p+1,,,,i-1]都小于x;nums[i,...,r]>=x nums[i], nums[p] = nums[p], nums[i] quicksort(nums,p,i-1) quicksort(nums,i+1,r) return
五:改进一:
考虑极端的情况:如果n个数都相同,插入排序是O(n),而快排则变成了平方级别的。考虑从两端划分:
i从左往右扫,j从右往左扫;
如果i>=j循环终止
否则交换i,j对应的值(这里相当于又找到了一个大于等于key和一个小于等于key的数,i++,j–)
(python没有do while 写成这个会比较简单)
def quicksort(nums,p,r): if p>=r: return key=nums[p] i=p+1 #从左往右 j=r #从右往左 while True: while i<=r and nums[i]<key: i+=1 while nums[j]>key: j-=1 if i>=j: break #此时nums[p+1,,,i-1]都小,注意i可能为r+1 #nums[j+1,r]都大 nums[i],nums[j]=nums[j],nums[i] i+=1 j-=1 nums[p],nums[j]=nums[j],nums[p] quicksort(nums,p,i-1) quicksort(nums,j+1,r) return
六:改进二:
如果对于排序好的数,选取第一个元素做划分会导致效率的降低(平方级别)。所以应该选择随机选择划分元素.
在 if的后面加上:
x=random.randint(p,r) nums[x],nums[p]=nums[p],nums[x]
七:改进三:
修改 if快速排序花费了大量的时间来排序很小的子数组,如果采用插入排序会更快
可以修改为:
if p-r<cutoff: return
其中,cutoff是一个小整数,然后选择其他排序算法进行排序。
相关文章推荐
- 排序总结:插入(简单和改进)、希尔、选择、冒泡、快速、堆排序、归并排序
- 常用算法总结之排序(三)----改进冒泡
- 快速排序:改进后的冒泡排序
- 八大排序算法:简单插入排序、冒泡排序、希尔排序、快速排序、堆排序、归并排序等总结。
- 冒泡排序,插入排序,快速排序 简单总结
- 常用排序算法总结(二) ---- 插入排序,快速排序
- 排序算法总结(五)快速排序
- 内排序算法总结——快速排序
- 排序算法总结(二)——快速排序、归并排序
- 各种排序算法总结----基数排序、归并排序、插入排序、冒泡排序、选择排序、快速排序、堆排序、希尔排序
- java相关总结4--冒泡、选择、快速、插入排序
- 快速排序的改进算法
- 冒泡,插入,折半插入,希尔,快速,简单选择排序的源代码总结
- 【排序算法】快速排序超级总结
- 排序序列排序算法总结(二)——快速排序、归并排序
- 快速排序改进
- 微软面试题:三路划分快速排序---针对重复关键字的改进
- 程序员面试宝典之数据结构基础----排序之快速排序(简单快速排序与改进快速排序)总结
- 快速排序-改进1
- 内排序(3)交换排序:改进的冒泡和快速排序