快速排序详解与实现
2017-12-09 12:49
155 查看
选一个序列中的值,所有元素跟这个值做比较,序列被分为两部分,然后对剩下每部分继续做相同操作。快排随机性很大,跟选取的值有关系,每次选值有可能将序列平均分为两份,也有可能做了无用功选取了最大或者最小的那个值,所以时间消耗上随机性很大.
Pythoe实现:
写快排的时候一定要注意对选取的比对值的处理,很容易造成死循环。例如我习惯性将队首值做为比对值,现在要做从小到大排序,如果我的序列队首已经是最小值了[1,3,9,2,6,5,4],快排后的结果仍然是[
1,3,9,2,6,5,4],快排后一定要将比对值剔除后再递归,否则将是个死循环。
时间复杂度上来分析,快排最理想的情况下比较次数=2(n-2),最差的情况相当于做了一次冒泡排序(n^2)/2-n/2,复杂度O(nlog2(n)),线性部分n越大每次比对越复杂,对数部分n扩大一倍相当于多递归一次而已。
空间复杂度方面来分析,快排的内存开销很大,为了不破坏原有的元素它必须开辟额外的内存空间保存比对后的结果,复杂度也是O(nlog2(n)),算法又来跟时间复杂度的由来一样.
最有分歧的一个问题来了:快排是不是稳定的?先说结论吧,个人觉得最标准的答案是”快排在牺牲效率的前提下可以稳定”.网上给的答案都是不稳定的,原因有2个.第一:每次排序选取比对值如果是随机选取的话肯定就不稳定了.第二:为了提高大小分组效率往往是首尾向中间对撞比对的,重复数据虽然因为值是相等的都会被分到一边,但是先后顺序得不到保障.如何才能稳定?每次用第一个元素做单向比对就能实现.
Pythoe实现稳定的快速排序:
Pythoe实现:
def sortList(list) : if len(list)>2 : #多于两条记录,进行一次快排 x = list[0] i = 0; j = len(list)-1 flag = 'right-left' while i<j : if flag=='right-left' : if list[j]<x : #互换位置 list[i]=list[j] list[j]=x #转变方向 flag='left-right' i+=1 else : j-=1 elif flag=='left-right' : if list[i]>x : #互换位置 list[j]=list[i] list[i] = x #转变方向 flag='right-left' j-=1 else : i+=1 #到此处为止一层快排就结束了 #要分别对i之前和j之后的部分再进行一次快排 return sortList(list[0:i])+[x]+sortList(list[j+1:]) elif len(list)==2 : #等于两条记录,比较大小 if list[0]>list[1] : list.reverse() return list else : return list originalList=[130,-177,141,-195,-4,98,117,-168,-62,181,167,-190,-100,46,53,39,74,-77,-129,168,92,-139,-106,-188,-50,82,-111,194,83,18] resultList = sortList(originalList) print(resultList)
写快排的时候一定要注意对选取的比对值的处理,很容易造成死循环。例如我习惯性将队首值做为比对值,现在要做从小到大排序,如果我的序列队首已经是最小值了[1,3,9,2,6,5,4],快排后的结果仍然是[
1,3,9,2,6,5,4],快排后一定要将比对值剔除后再递归,否则将是个死循环。
时间复杂度上来分析,快排最理想的情况下比较次数=2(n-2),最差的情况相当于做了一次冒泡排序(n^2)/2-n/2,复杂度O(nlog2(n)),线性部分n越大每次比对越复杂,对数部分n扩大一倍相当于多递归一次而已。
空间复杂度方面来分析,快排的内存开销很大,为了不破坏原有的元素它必须开辟额外的内存空间保存比对后的结果,复杂度也是O(nlog2(n)),算法又来跟时间复杂度的由来一样.
最有分歧的一个问题来了:快排是不是稳定的?先说结论吧,个人觉得最标准的答案是”快排在牺牲效率的前提下可以稳定”.网上给的答案都是不稳定的,原因有2个.第一:每次排序选取比对值如果是随机选取的话肯定就不稳定了.第二:为了提高大小分组效率往往是首尾向中间对撞比对的,重复数据虽然因为值是相等的都会被分到一边,但是先后顺序得不到保障.如何才能稳定?每次用第一个元素做单向比对就能实现.
Pythoe实现稳定的快速排序:
def sortList(list) : if len(list)>2 : #多于两条记录,进行一次快排 x = list[0] leftList=[] rightList=[] for n in list[1:] : if n<x : leftList.append(n) else : rightList.append(n) return sortList(leftList)+[x]+sortList(rightList) elif len(list)==2 : #等于两条记录,比较大小 if list[0]>list[1] : list.reverse() return list else : return list originalList=[-130,-10,1,28,-39,-88,79,60,10,1,38] resultList = sortList(originalList) print(resultList)
相关文章推荐
- STL sort 函数实现详解 作者:fengcc 原创作品 转载请注明出处 前几天阿里电话一面,被问到STL中sort函数的实现。以前没有仔细探究过,听人说是快速排序,于是回答说用快速排序实现的
- 快速排序详解以及java实现
- 快速排序详解--C语言实现
- 快速排序详解 Java实现
- 快速排序详解--Java实现
- C语言中快速排序和插入排序优化的实现
- 快速排序java实现
- C++实现快速排序
- php实现快速排序
- java实现快速排序、插入排序、选择排序、冒泡排序算法
- Java中快速排序的实现
- 快速排序C++实现(递归,非递归)
- 快速排序c语言实现
- 几种排序算法的C++实现——快速排序、堆排序、基数排序
- C++实现快速冒泡排序
- 排序算法(三)冒泡、选择排序的Python实现及算法优化详解 推荐
- 快速排序C++实现
- 算法代码实现之三向切分快速排序,C/C++实现
- 插入排序,希尔排序,堆排序,归并排序,快速排序Java实现
- Java实现排序算法之快速排序