Python實現排序算法(上)

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

# 用Python實現了 
# 冒泡排序,選擇排序,插入排序,快速排序,歸併排序


"""
Author:     [email protected]
datetime:   2018/11/4 下午15:19
"""

from __future__ import absolute_import, division, print_function, \
    unicode_literals

import time
from functools import wraps
import random

def calculate_time(func):
    '''
    打印函數運行時間
    :param func: 目標函數
    :return: 裝飾後的函數
    '''
    @wraps(func)
    def wrapper(*args, **kwargs):
        start = time.time()
        res = func(*args, **kwargs)
        print (time.time() - start)
        return res
    return wrapper

@calculate_time
def out_wrapper(func, *args, **kwargs):
    '''
    裝飾遞歸函數使用的外層包裝函數
    :param func: 目標函數
    :param args kwargs: 目標函數所有參數
    :return: 目標函數返回值
    '''
    return func(*args, **kwargs)

# -------- 冒泡排序 --------

def bubble_sort(l):
    '''
    冒泡排序
    :param l: list 目標列表
    :return: list 冒泡排序後的目標列表
    '''
    for k in range(len(l)):
        for i in range(len(l) - k):
            if i < len(l) - 1:
                if l[i] > l[i+1]:
                    l[i], l[i+1] = l[i+1], l[i]

    return l

# -------- 選擇排序 --------

def select_sort(l):
    '''
    選擇排序
    :param l: list 目標列表
    :return: list 選擇排序後的目標列表
    '''
    for i in range(len(l)):
        for j in range(i, len(l)):
            if l[j] < l[i]:
                l[i] = l[j]
    return l

# -------- 插入排序 --------

def insert_sort(l):
    '''
    插入排序
    :param l: list 目標列表
    :return: list 插入排序後的目標列表
    '''
    for i in range(1, len(l)):
        for j in range(i):
            if l[i] < l[j]:
                for k in range(i-1, j-1, -1):
                    l[k+1] = l[k]
                l[j] = l[i]
                break
    return l

# -------- 快速排序 --------

def quick_sort(l, start, end):
    '''
    快速排序
    :param l: list 目標列表
    :param start: int 目標列表頭索引
    :param end: int 目標列表尾索引
    :return: list 快速排序後的目標列表
    '''
    if start <= end:

        i, j = start, end
        base = l[i]
        while i < j:

            while i < j and l[j] >= base:
                j -= 1
            l[i] = l[j]

            while i < j and l[i] <= base:
                i += 1
            l[j] = l[i]

        l[i] = base


        quick_sort(l, start, i - 1)
        quick_sort(l, i + 1, end)

    return l

# -------- 歸併排序 --------

def merge(l, r):
    '''
    合併兩個有序列表爲一個新的有序列表
    :param l: list 目標有序列表l
    :param r: list 目標有序列表r
    :return: list 合併後的新有序列表
    '''
    tar = []
    i, j = 0, 0
    while i < len(l) and j < len(r):
        if l[i] <= r[j]:
            tar.append(l[i])
            i += 1
        else:
            tar.append(r[j])
            j += 1

    tar += r[j:]
    tar += l[i:]

    return tar

def merge_sort(l):
    '''
    歸併排序
    :param l: list 目標列表
    :return: list 歸併排序後的目標列表
    '''
    length = len(l)
    if length >= 2:
        index = int(length / 2)
        llist_ = l[:index]
        rlist_ = l[index:]

        llist = merge_sort(llist_)
        rlist = merge_sort(rlist_)

        l = merge(llist, rlist)
        return l
    else:
        return l

if __name__ == "__main__":

    l = [random.randint(1, 100000) for x in range(10000)]
    bubble_sort_list = out_wrapper(bubble_sort, l)

    l = [random.randint(1, 100000) for x in range(10000)]
    select_sort_list = out_wrapper(select_sort, l)

    l = [random.randint(1, 100000) for x in range(10000)]
    insert_sort_list = out_wrapper(insert_sort, l)

    l = [random.randint(1, 100000) for x in range(10000)]
    quick_sort_list = out_wrapper(quick_sort, l, 0, len(l)-1)

    l = [random.randint(1, 100000) for x in range(10000)]
    merge_sort_list = out_wrapper(merge_sort, l)

打印時間:

冒泡:12.2775378227
選擇:3.05686402321
插入:4.5859670639
快速:0.02716588974
歸併:0.0529198646545

注意:快速排序的快慢與基準的選擇息息相關,最壞情況爲O(n^2),所以當出現大量相同數據,或是大部分已排序,用快速排序效率會大幅降低

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章