Python实现排序算法(上)

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

# 用Python实现了 
# 冒泡排序,选择排序,插入排序,快速排序,归并排序


"""
Author:     wukai15937@gmail.com
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),所以当出现大量相同数据,或是大部分已排序,用快速排序效率会大幅降低

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值