几种快速排序的耗时比较

几种快速排序的耗时比较

数组长度=10^4固定pivot(首)随机pivot三数取中三数取中+插排五数取中
随机数组0.03429 s0.04581 s0.0415 s  
升序数组4.98177 s0.03306 s0.03784 s  
降序数组4.96196 s0.03328 s0.0342 s  
重复数组4.29686 s4.69243 s4.53609 s  


Quick Sort 快速排序

本质分治思想
特点:每经过一次快排,轴点(pivot)元素必然就位!

过程:每经过一次快排,枢轴元素将所处理区域划分为“小元素”和“大元素”两段,并通过递归不断划分,最终得到一个排序的序列。

核心技巧:每一次的partition都比较平均。

1.如果每次划分都将所处理的区域划分为长度基本相等的两段
$$\frac{n}{2^k}=1\rightarrow k=log_{2}n$$
很显然只需大约log n层划分,就能使最底层的每个分段长度不超过1。而每一趟划分的过程中,关键码比较次数不超过对象长度。所以当前情况下,元素比较次数不超过:
$$O(nlogn)$$
2.最坏情况:每次划分得到的两段总有一段为空,总的比较次数是
$$O(n^2)$$


方法1. 固定枢轴:

Created on Sun Apr  8 10:35:06 2018


@author: yzdeng
"""
import numpy as np
import timeit 
import sys   
sys.setrecursionlimit(1000000)

#固定pivot(数组首元素做pivot)
def quick_sort1(lst,l,r):
    if l>=r:
        return
    i=l
    j=r
    pivot=lst[i]
    while i<j:
        while i<j and lst[j]>=pivot:
            j-=1
        if i<j:
            lst[i]=lst[j]
            i+=1
        while i<j and lst[i]<=pivot:
            i+=1
        if i<j:
            lst[j]=lst[i]
            j-=1
    lst[i]=pivot
    quick_sort1(lst,l,i-1)
    quick_sort1(lst,i+1,r)
    return lst


方法2. 随机枢轴:

#!/usr/bin/env python3
# -*- coding: utf-8 -*-

""" 
Created on Sun Apr  8 17:20:36 2018 
 
@author: dengyuzhao 
"""  

from random import choice  
import numpy as np  
import timeit   
import sys     
sys.setrecursionlimit(1000000)  
  
def quick_sort1(lst,l,r):  
    if l>=r:  
        return  
    a=np.arange(l,r+1)  
    p=choice(a) 
    i=l  
    j=r  
    pivot=lst[p]  
    lst[p]=lst[i]
    while i<j:  
        while i<j and lst[j]>=pivot:  
            j-=1  
        if i<j:  
            lst[i]=lst[j]  
            i+=1  
        while i<j and lst[i]<=pivot:  
            i+=1  
        if i<j:  
            lst[j]=lst[i]  
            j-=1  
    lst[i]=pivot  
    quick_sort1(lst,l,i-1)  
    quick_sort1(lst,i+1,r)  
    return lst  
  
#test:  
  
a1=np.random.normal(100,100,(10000,))  
b1=list(a1)  
print(timeit.Timer(lambda:quick_sort1(b1,0,9999)).timeit(1))  
a2=np.arange(10000)  
b2=list(a2)  
print(timeit.Timer(lambda:quick_sort1(b2,0,9999)).timeit(1))  
a3=np.arange(10000,0,-1)  
b3=list(a3)  
print(timeit.Timer(lambda:quick_sort1(b3,0,9999)).timeit(1))  
a4=[2]*10000  
print(timeit.Timer(lambda:quick_sort1(a4,0,9999)).timeit(1))  


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值