python實現簡單排序算法


算法

遞歸兩個特點:
調用自身
有窮調用
計算規模越來越小,直至最后結束


用裝飾器修飾一個遞歸函數時會出現問題,這個問題產生的原因是遞歸的函數也不停的使用裝飾器。
解決方法是,只讓裝飾器調用一次即可,那么可以出創建一個新的普通函數,執行一下遞歸函數,並放回遞歸函數的返回值,給這個普通函數加上裝飾器即可。

尾遞歸和正常循環時間復雜度相同,尾遞歸:每次遞歸尾部return遞歸函數

算法關鍵:
有序區和無序區,隨着算法的推進,有序區越來越大,無序區越來越小,直至消失,完成排序


代碼:
import random

import time

import sys

import copy
#裝飾器

def time_cost(func):
def wrapper(*args,**kwargs):
sTime = time.time()
func(*args,**kwargs)
print("Time cost:%s"%(time.time()-sTime))
print(args[0])
return wrapper

#冒泡排序:
#每一次循環從端點處比較n次選出最大或最小的數,一趟結束n--,每次里層循環n-i-1次。

@time_cost
def bubble_sort(list):
    print("\nbubble_sort:")
    for i in range(len(list)-1):
        tag = 0
        for j in range(len(list)-i-1):
            if list[j] > list[j+1]:
                list[j],list[j+1] = list[j+1],list[j]
                tag = 1
        if not tag:
            return

 

 

#選擇排序
#每次選出最小的數,放在n,每趟結束n++,每次里層循環(i+1,len(list))

@time_cost
def select_sort(list):
    print("\nselect_sort:")
    for i in range(len(list)-1):
        min = i
        for j in range(i+1,len(list)):
            if list[min] > list[j]:
                min = j
        if min != i:
            list[i],list[min] = list[min],list[i]

 

 

#插入排序
#分有序區和無序區,列表前面是有序區,后面是無序區,每次從無序區的首位取一個元素,與有序區元素依次比較,放到合適的位置,直到無序區元素取完

@time_cost
def insert_sort(list):
    print("\ninsert_sort:")
    for i in range(len(list)):
        tag = 0
        for j in range(i,0,-1):
            if list[j] < list[j-1]:
                list[j],list[j-1] = list[j-1],list[j]
                tag = 1
            if not tag:
                break

 

 

#快速排序
#遞歸實現,取一個數(列表第一個),使得列表左邊的元素比此數都小,列表右邊的元素比此數都大,依據此數位置切割出左右兩邊列表分別進行遞歸,直至列表只有一個元素

def part_sort(list,left,right):
    temp = list[left]
    while left < right:
        while left < right and temp <= list[right]:
            right -= 1
        list[left] = list[right]
        while left < right and temp >= list[left]:
            left += 1
        list[right] = list[left]
    list[left] = temp
    return left


def _quckly_sort(list,left,right):
    if left < right:
        mid = part_sort(list,left,right)
        _quckly_sort(list,left,mid-1)
        _quckly_sort(list,mid+1,right)

@time_cost
def quckly_sort(list):
    print("\nquckly_sort:")
    return _quckly_sort(list,0,len(list)-1)

 


#快排的時間復雜度為O(nlogn)
#冒泡、選擇、插入排序的時間復雜度為O(n^2)
#一般來說處理大數據排序問題,快排比前面三種排序快好幾個數量級

#但是如果碰到極端情況,例如:列表是反序排列的
#快排的時間復雜度退化成O(n^2)
#由於自身有遞歸加大開銷,會使相同排序比其他三種排序耗時更久


#系統自帶排序 sort()
#大多數編程語言系統排序使用的都是快速排序
#python系統自帶的排序使用的是C語言編寫的快排,比python寫的快排快一個數量級

sort(list)


#一般來說系統都有限制最大遞歸層數
#修改系統最大遞歸層數
import sys
sys.setrecursionlimit(10000)

 


#比較4種排序,當排序個數為10000時
#bubble_sort:
#Time cost:17.794017791748047

#select_sort:
#Time cost:5.8113322257995605

#insert_sort:
#Time cost:15.441883087158203

#_quckly_sort:
#Time cost:0.044002532958984375
#快排效率非常高

 


#堆排序
#當各節點是順序存儲時,且必須是完全二叉樹
#父節點與左孩子關系: i ~ 2i+1
#父節點與右孩子關系: i ~ 2i+2
#首先將列表元素建堆,形成大根堆
#然后循環調整大根堆,取堆頂元素,生成有序序列
#時間復雜度O(nlogn)

 

def sift(list,low,high):
    i = low
    j = 2 * i + 1
    temp = list[i]
    while j <= high:
        if j < high and list[j] < list[j+1]:
            j += 1
        if temp < list[j]:
            list[i] = list[j]
            i = j
            j = 2 * i + 1
        else:
            break
    list[i] = temp
    list[low],list[high] = list[low],list[high]



@time_cost
def heap_sort(list):
    print("\nheap_sort:")
    n = len(list)
    for i in range(n // 2 - 1, -1, -1):
        sift(list, i, n - 1)
    for i in range(n-1, -1, -1):
        list[0],list[i] = list[i],list[0]
        sift(list, 0, i - 1)

 

 

#歸並排序
#一次歸並,將兩個排序好的列表合並成一個有序列表
#首先將一個無序列表遞歸分解成只有1個元素的n個列表
#將所有分解的列表兩兩執行一次歸並算法,最終合成一個有序列表
#時間復雜度O(nlogn)
#空間復雜度O(n)每個一次歸並都創建一個列表

def ont_megre_sort(list,low,mid,high):
    i = low
    j = mid + 1
    ltmp = []
    while i <= mid and j <= high:
        if list[i] < list[j]:
            ltmp.append(list[i])
            i += 1
        else:
            ltmp.append(list[j])
            j += 1
    while i <= mid:
        ltmp.append(list[i])
        i += 1
    while j <= high:
        ltmp.append(list[j])
        j += 1
    list[low:high+1] = ltmp


def _megre_sort(list,low,high):
    if low < high:
        mid = (low+high)//2
        _megre_sort(list,low,mid)
        _megre_sort(list,mid+1,high)
        ont_megre_sort(list,low,mid,high)

@time_cost
def megre_sort(list):
    print("\nmegre_sort:")
    return _megre_sort(list,0,len(list)-1)

 

 

 

#一般來說 快速排序 < 歸並排序 < 堆排序
#快排極端情況下速度慢,不穩定
#歸並排序需要空間開銷
#堆排序相對穩定
#時間復雜度O(n)

 

 

#希爾排序
#一種分組插入排序算法
#根據定義d為間隔分組,對每個小分組做一次直接插入排序
#d逐漸縮小,列表相對有序,直至d=1,成為直接插入排序,最后一次循環使列表徹底有序
#時間復雜度O((1+T)n)=O(1.3n)

 

@time_cost
def shell_sort(list):
    print("\nshell_sort:")
    gap = len(list) // 2
    while gap > 0:
        for i in range(gap,len(list)):
            temp = list[i]
            j = i - gap
            while j >= 0 and temp < list[j]:
                list[j + gap] = list[j]
                j -= gap
            list[j + gap] = temp
        gap //= 2

 

 

#----------------------------------------------總結------------------------------------------------#
# 排序方法            時間復雜度             穩定性      代碼復雜度 #
# #
#             最壞情況    平均情況     最好情況                   #
# 冒泡排序          O(n^2)      O(n^2)           O(n)      穩定        簡單        #  
# #
# 直接選擇排序        O(n^2)      O(n^2)         O(n^2)      不穩定        簡單        #
# #
# 直接插入排序        O(n^2)      O(n^2)         O(n^2)     穩定        簡單        #
# #
# 快速排序        O(n^2)      O(nlogn)       O(nlogn)       不穩定                    較復雜      #
# #
# 堆排序           O(nlogn)    O(nlogn)       O(nlogn)     穩定                        復雜        #
# #
# 歸並排序            O(nlogn)    O(nlogn)        O(nlogn)     穩定       較復雜      #
# #
# 希爾排序        O(1.3n)                   不穩定                    較復雜      #
# #
# #
#-----------------------------------------------------------------------------------------------------------------------------#

全部代碼

__author__ = 'cq'


import time
import random
import sys
import copy

def time_cost(func):
    def wrapper(*args,**kwargs):
        sTime = time.time()
        func(*args,**kwargs)
        print("Time cost:%s"%(time.time()-sTime))
        print(args[0])
    return wrapper

#-------------------冒泡排序-----------------------#
@time_cost
def bubble_sort(list):
    print("\nbubble_sort:")
    for i in range(len(list)-1):
        tag = 0
        for j in range(len(list)-i-1):
            if list[j] > list[j+1]:
                list[j],list[j+1] = list[j+1],list[j]
                tag = 1
        if not tag:
            return

#-------------------插入排序-----------------------#
@time_cost
def insert_sort(list):
    print("\ninsert_sort:")
    for i in range(len(list)):
        tag = 0
        for j in range(i,0,-1):
            if list[j] < list[j-1]:
                list[j],list[j-1] = list[j-1],list[j]
                tag = 1
            if not tag:
                break

#-------------------選擇排序-----------------------#
@time_cost
def select_sort(list):
    print("\nselect_sort:")
    for i in range(len(list)-1):
        min = i
        for j in range(i+1,len(list)):
            if list[min] > list[j]:
                min = j
        if min != i:
            list[i],list[min] = list[min],list[i]

#-------------------快速排序-----------------------#
def part_sort(list,left,right):
    temp = list[left]
    while left < right:
        while left < right and temp <= list[right]:
            right -= 1
        list[left] = list[right]
        while left < right and temp >= list[left]:
            left += 1
        list[right] = list[left]
    list[left] = temp
    return left


def _quckly_sort(list,left,right):
    if left < right:
        mid = part_sort(list,left,right)
        _quckly_sort(list,left,mid-1)
        _quckly_sort(list,mid+1,right)

@time_cost
def quckly_sort(list):
    print("\nquckly_sort:")
    return _quckly_sort(list,0,len(list)-1)

#-------------------堆排序-----------------------#
def sift(list,low,high):
    i = low
    j = 2 * i + 1
    temp = list[i]
    while j <= high:
        if j < high and list[j] < list[j+1]:
            j += 1
        if temp < list[j]:
            list[i] = list[j]
            i = j
            j = 2 * i + 1
        else:
            break
    list[i] = temp
    list[low],list[high] = list[low],list[high]



@time_cost
def heap_sort(list):
    print("\nheap_sort:")
    n = len(list)
    for i in range(n // 2 - 1, -1, -1):
        sift(list, i, n - 1)
    for i in range(n-1, -1, -1):
        list[0],list[i] = list[i],list[0]
        sift(list, 0, i - 1)


#-------------------歸並排序-----------------------#
def ont_megre_sort(list,low,mid,high):
    i = low
    j = mid + 1
    ltmp = []
    while i <= mid and j <= high:
        if list[i] < list[j]:
            ltmp.append(list[i])
            i += 1
        else:
            ltmp.append(list[j])
            j += 1
    while i <= mid:
        ltmp.append(list[i])
        i += 1
    while j <= high:
        ltmp.append(list[j])
        j += 1
    list[low:high+1] = ltmp


def _megre_sort(list,low,high):
    if low < high:
        mid = (low+high)//2
        _megre_sort(list,low,mid)
        _megre_sort(list,mid+1,high)
        ont_megre_sort(list,low,mid,high)

@time_cost
def megre_sort(list):
    print("\nmegre_sort:")
    return _megre_sort(list,0,len(list)-1)


#-------------------希爾排序-----------------------#
@time_cost
def shell_sort(list):
    print("\nshell_sort:")
    gap = len(list) // 2
    while gap > 0:
        for i in range(gap,len(list)):
            temp = list[i]
            j = i - gap
            while j >= 0 and temp < list[j]:
                list[j + gap] = list[j]
                j -= gap
            list[j + gap] = temp
        gap //= 2








def main():
    #生成列表
    list0 = list(range(100))
    first_name = ["","","","",""]
    second_name = ["","","","",""]
    third_name = ["","","","",""]
    listname = [
        {"id":"1000"+str(i),
         "name":random.choice(first_name)+
                random.choice(second_name)+
                random.choice(third_name),
         "age":random.randint(16,60)
        } for i in range(10)
    ]
    random.shuffle(list0)
    random.shuffle(listname)

    #copy四份打亂后的列表
    list1 = copy.deepcopy(list0)
    list2 = copy.deepcopy(list0)
    list3 = copy.deepcopy(list0)
    list4 = copy.deepcopy(list0)
    list5 = copy.deepcopy(list0)
    list6 = copy.deepcopy(list0)
    list7 = copy.deepcopy(list0)

    #設置遞歸深度
    sys.setrecursionlimit(10000)


    print("sort_list:")
    print(list0)

    #排序算法
    bubble_sort(list1)
    select_sort(list2)
    insert_sort(list3)
    quckly_sort(list4)
    heap_sort(list5)
    megre_sort(list6)
    shell_sort(list7)


    print("\npractice to sort this list:")
    for i in listname:
        print(i)

if "__main__" == __name__:
    main()
View Code

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM