算法基础:快排

什么是快排?

 

排序思路

 

排序代码

快速排序代码——第一步

def quick_sort_x(data, left, right):
    if left < right:
        mid = partition(data, left, right)
        quick_sort_x(data, left, mid - 1)
        quick_sort_x(data, mid + 1, right)

怎么写partition函数

快速排序代码——第二步

def partition(data, left, right):
    tmp = data[left]
    while left < right:
        while left < right and data[right] >= tmp:
            right -= 1
        data[left] = data[right]
        while left < right and data[left] <= tmp:
            left += 1
        data[right] = data[left]
    data[left] = tmp
    return left

还不理解partition函数?

效率性能

   快排和冒泡算法性能比较

import random
import time
import copy

def cal_time(func):
    def wrapper(*args, **kwargs):
        t1 = time.time()
        result = func(*args, **kwargs)
        t2 = time.time()
        print("%s running time: %s secs." % (func.__name__, t2 - t1))
        return result
    return wrapper


@cal_time
def bubble_sort_1(li):
    for i in range(len(li) - 1):
        exchange = False
        for j in range(len(li) - i - 1):
            if li[j] > li[j+1]:
                li[j], li[j+1] = li[j+1], li[j]
                exchange = True
        if not exchange:
            break

def quick_sort_x(data, left, right):
    if left < right:
        mid = partition(data, left, right)
        quick_sort_x(data, left, mid - 1)
        quick_sort_x(data, mid + 1, right)

def partition(data, left, right):
    tmp = data[left]
    while left < right:
        while left < right and data[right] >= tmp:
            right -= 1
        data[left] = data[right]
        while left < right and data[left] <= tmp:
            left += 1
        data[right] = data[left]
    data[left] = tmp
    return left


@cal_time
def quick_sort(data):
    return quick_sort_x(data, 0, len(data) - 1)


data = list(range(10000))
random.shuffle(data)
data1 = copy.deepcopy(data)
data2 = copy.deepcopy(data)

bubble_sort(data1)
quick_sort(data2)

下面分别是10000和100000列表的时间

data = list(range(10000))
bubble_sort running time: 10.56360411643982 secs.
quick_sort running time:  0.03200173377990723 secs.

data = list(range(100000))
bubble_sort running time: 1173.2021033763885 secs.
quick_sort running time:  0.4220242500305176 secs.

 结论:元素越多,性能差距越明显

 1、因为冒泡每一趟只完成一个元素的归位

 2、而快排每一趟不至一个元素的归位,相同的时间归位的元素越多说明效率就越高

 3、从复杂度方面讲:

冒泡是:n*n      64*64

快排是:O(logn)  64*6

         

 

快排、冒泡、系统自带排序性能比较

import random
import time
import copy
import sys


def cal_time(func):
    def wrapper(*args, **kwargs):
        t1 = time.time()
        result = func(*args, **kwargs)
        t2 = time.time()
        print("%s running time: %s secs." % (func.__name__, t2 - t1))
        return result

    return wrapper


@cal_time
def bubble_sort(li):
    for i in range(len(li) - 1):
        exchange = False
        for j in range(len(li) - i - 1):
            if li[j] > li[j + 1]:
                li[j], li[j + 1] = li[j + 1], li[j]
                exchange = True
        if not exchange:
            break


def quick_sort_x(data, left, right):
    if left < right:
        mid = partition(data, left, right)
        quick_sort_x(data, left, mid - 1)
        quick_sort_x(data, mid + 1, right)


def partition(data, left, right):
    tmp = data[left]
    while left < right:
        while left < right and data[right] >= tmp:
            right -= 1
        data[left] = data[right]
        while left < right and data[left] <= tmp:
            left += 1
        data[right] = data[left]
    data[left] = tmp
    return left


@cal_time
def quick_sort(data):
    return quick_sort_x(data, 0, len(data) - 1)


@cal_time
def sys_sort(data):
    return data.sort()


data = list(range(1000000))
random.shuffle(data)
data1 = copy.deepcopy(data)
data2 = copy.deepcopy(data)
data3 = copy.deepcopy(data)


quick_sort(data2)
sys_sort(data3)
bubble_sort(data1)

测试结果:

quick_sort running time: 5.9070000648498535 secs.
sys_sort running time: 0.559999942779541 secs.

结论:最快的是系统自带排序,下来是快排,最后是冒泡,系统自带排序为什么会最快了?

def sort(self, key=None, reverse=False): # real signature unknown; restored from __doc__
        """ L.sort(key=None, reverse=False) -> None -- stable sort *IN PLACE* """
        pass

系统自带排序为什么会最快了?

上面是系统的类,就一个pass,因为自带的是用C写的.绝大多数的语言,默认的都是快排,但是python不是是用C语言写的

不改装逼的时候不要装逼,自己写的时候,就调用系统自带的快排。

哪我们为什么要学算法哪?

算法是能力的一个体现,就比如你数学学的好,说明你思维能力好

问题

[9999, 9998, 9997, 9996, 9995, 9994, 9993, 9992, 9991, 9990, 9989, 9988,...0] 就像这样全部是倒序

import random
import time
import copy
import sys

def cal_time(func):
    def wrapper(*args, **kwargs):
        t1 = time.time()
        result = func(*args, **kwargs)
        t2 = time.time()
        print("%s running time: %s secs." % (func.__name__, t2 - t1))
        return result
    return wrapper

@cal_time
def bubble_sort_1(li):
    for i in range(len(li) - 1):
        exchange = False
        for j in range(len(li) - i - 1):
            if li[j] > li[j+1]:
                li[j], li[j+1] = li[j+1], li[j]
                exchange = True
        if not exchange:
            break

def quick_sort_x(data, left, right):
    if left < right:
        mid = partition(data, left, right)
        quick_sort_x(data, left, mid - 1)
        quick_sort_x(data, mid + 1, right)

def partition(data, left, right):
    tmp = data[left]
    while left < right:
        while left < right and data[right] >= tmp:
            right -= 1
        data[left] = data[right]
        while left < right and data[left] <= tmp:
            left += 1
        data[right] = data[left]
    data[left] = tmp
    return left

@cal_time
def quick_sort(data):
    return quick_sort_x(data, 0, len(data) - 1)

@cal_time
def sys_sort(data):
    return data.sort()

sys.setrecursionlimit(100000)
a = range(10000)
data = list(reversed(a))
data1 = copy.deepcopy(data)
data2 = copy.deepcopy(data)
data3 = copy.deepcopy(data)

bubble_sort(data1)
quick_sort(data2)
sys_sort(data3)

测试结果如下:

bubble_sort running time: 0.20701169967651367 secs.
quick_sort running time:  0.1020057201385498 secs.
sys_sort running time:    0.0 secs.

关于递归一定要添加:sys.setrecursionlimit(100000),因为Python中递归的最大次数的限制不加报如下错误:

当在我自己的机器运行以上代码时,发现最多能打印到998,然后就会抛出 “RuntimeError: maximum recursion depth exceeded” 的错误了。 嘿,还真有限制。但转念一想,python不会这么弱吧。经过一番查找,发现这是python专门设置的一种机制用来防止无限递归造成Python溢出崩溃, 最大递归次数是可以重新调整的。 (http://docs.python.org/2/library/sys.html#sys.setrecursionlimit),修改代码如下:

sys.setrecursionlimit(100000)
a = range(10000)
data = list(reversed(a))
#data.sort()
#random.shuffle(data)
data1 = copy.deepcopy(data)
data2 = copy.deepcopy(data)
data3 = copy.deepcopy(data)

bubble_sort(data1)
quick_sort(data2)

还需要注意如果:data = list(range(1000, 1, -1)) 中的1000设置成10000就会报如下错误:

总结

1、快排最好情况下:【0,1,2,3,4,5,6,...,9999】

sys.setrecursionlimit(100000)
data = list(range(1000))
data1 = copy.deepcopy(data)
data2 = copy.deepcopy(data)
data3 = copy.deepcopy(data)

bubble_sort_1(data1)
quick_sort(data2)
sys_sort(data3)

测试结果如下:

bubble_sort_1 running time: 0.0 secs.
quick_sort running time: 0.07200407981872559 secs.
sys_sort running time: 0.0 secs.

2、正常情况下:[15, 781, 698, 460, 445, 522, 470, 225, 925, 840, 334, 664, 434...2]

sys.setrecursionlimit(100000)
data = list(range(1000))
random.shuffle(data)
data1 = copy.deepcopy(data)
data2 = copy.deepcopy(data)
data3 = copy.deepcopy(data)

bubble_sort_1(data1)
quick_sort(data2)
sys_sort(data3)

 测试结果如下:

bubble_sort_1 running time: 0.14500832557678223 secs.
quick_sort running time:    0.002000093460083008 secs.
sys_sort running time:      0.0009999275207519531 secs.

3、最坏情况下:[999, 998, 997, 996, 995, 994, 993, 992,...0]

sys.setrecursionlimit(100000)
a = range(1000)
data = list(reversed(a))
data1 = copy.deepcopy(data)
data2 = copy.deepcopy(data)
data3 = copy.deepcopy(data)

bubble_sort(data1)
quick_sort(data2)
sys_sort(data3)

 测试结果如下:

bubble_sort_1 running time: 0.2170124053955078 secs.
quick_sort running time:    0.08100461959838867 secs.
sys_sort running time: 0.0 secs.

下图为冒泡、快排和系统自带的对比表

 

 

  

posted @ 2019-12-07 22:09  活的潇洒80  阅读(404)  评论(0)    收藏  举报