python--幾種快速排序的實現以及運行時間比較

快速排序的基本思想:首先選定一個數組中的一個初始值,將數組中比該值小的放在左邊,比該值大的放在右邊,而後分別對左邊的數組進行如上的操做,對右邊的數組進行如上的操做。(分治+遞歸)python

1.利用匿名函數lambda算法

匿名函數的基本用法func_name  = lambda x:array,冒號左邊的x表明傳入的參數,冒號右邊的array表明返回值,固然名字是能夠本身取的。數組

quick_sort = lambda array: \
    array if len(array) <= 1 \
        else quick_sort([item for item in array[1:] if item <= array[0]]) \
             + [array[0]] + \
             quick_sort([item for item in array[1:] if item > array[0]])

2.將匿名函數拆解封裝爲函數app

def func2(array):
    if len(array)<=1:
        return array
    tmp = array[0]
    left = [x for x in array[1:] if x<=tmp]
    right = [x for x in array[1:] if x>tmp]
    return func2(left) + [tmp] + func2(right)

3.網上常見的dom

def func2(array,left,right):
    if left>=right:
        return
    low=left
    high=right
    tmp=array[low]
    while left<right:
        while left<right and array[right]>tmp:
            right-=1
        array[left] = array[right]
        while left<right and array[left]<=tmp:
            left+=1
        array[right]=array[left]
    array[right]=tmp
    func2(array,low,left-1)
    func2(array,left+1,high)

4.算法導論裏面的ide

def func3(array, l, r):
    if l < r:
        q = partition(array, l, r)
        func3(array, l, q - 1)
        func3(array, q + 1, r)

def partition(array, l, r):
    x = array[r]
    i = l - 1
    for j in range(l, r):
        if array[j] <= x:
            i += 1
            array[i], array[j] = array[j], array[i]
    array[i + 1], array[r] = array[r], array[i + 1]
    return i + 1

5.利用棧實現非遞歸版本函數

def func4(array, l, r):
    if l >= r:
        return
    stack = []
    stack.append(l)
    stack.append(r)
    while stack:
        low = stack.pop(0)
        high = stack.pop(0)
        if high - low <= 0:
            continue
        x = array[high]
        i = low - 1
        for j in range(low, high):
            if array[j] <= x:
                i += 1
                array[i], array[j] = array[j], array[i]
        array[i + 1], array[high] = array[high], array[i + 1]
        stack.extend([low, i, i + 2, high])

6.python內置的測試

sorted(array)

原本是想利用裝飾器來測一下每一個函數的運行時間的,可是因爲快排裏面存在遞歸,使用裝飾器會報錯,就只好一個個計算了。這裏仍是貼一下用裝飾器計算時間的代碼:ui

def count_time(func):
    @wraps(func)
    def helper(func,*args,**kwargs):
        start=time()
        result = func(*args,**kwargs)
        end=time()
        print("函數:", func.__name__, "運行時間:", round(end - start, 4), "s")
        return result
    return helper

這裏咱們的輸入是隨機生成的在0-100間的整數,咱們測試一下在不一樣數量下的消耗時間:spa

from functools import wraps
from random import randint
from time import time

func1_start =time()
res = quick_sort(array)
func1_end =time()
print("函數:func1 運行時間:", round(func1_end - func1_start, 4), "s")

func2_start =time()
func2(array)
func2_end =time()
print("函數:func2 運行時間:", round(func2_end - func2_start, 4), "s")

func3_start =time()
func3(array,0,len(array)-1)
func3_end =time()
print("函數:func3 運行時間:", round(func3_end - func3_start, 4), "s")

func4_start =time()
func4(array,0,len(array)-1)
func4_end =time()
print("函數:func4 運行時間:", round(func4_end - func4_start, 4), "s")

func5_start =time()
func5(array,0,len(array)-1)
func5_end =time()
print("函數:func5 運行時間:", round(func5_end - func5_start, 4), "s")

func6_start =time()
sorted(array)
func6_end =time()
print("函數:func6 運行時間:", round(func6_end - func6_start, 4), "s")

輸入array的定義:

array = [randint(0,100) for i in range(5000)]

須要注意的是,隨着數據量的增長,方法4,也就是算法導論中的會出現如下問題:

 這是由於python中的遞歸深度是有必定限制的,可使用以下方法暫時解決該問題:

import sys
sys.setrecursionlimit(100000)

同時,方法4還會出現內存溢出問題,方法4也太坑了。

 最後對比一下這些方法消耗的時間:

 總結:

  • 方法1、方法二速度較快,同時也較好理解,想要學會快速排序,只要記住方法二便可;
  • python內置的排序速度仍是最快的呀;
相關文章
相關標籤/搜索