Python實現常用排序

選擇排序

基本思想:各類排序的共同點,個人認爲可以把原始的數據序列,劃分爲有序序列與無序序列。有序序列開始可能爲0,在每一次操作(循環或者遞歸)後,有序序列數目會加1,無序序列數目會減一,代碼走完後,原本的數據序列完全變成有序序列。

關於選擇排序,例如初始序列是5,3,1,2,4.

1.搜索整個列表,找到最小項的位置,如果該位置不是列表第一項。則交換兩項位置。

2.從第二項開始一次往後搜索與替換。

def selectionSort(lyst):
    for i in range (len(lyst)):
        minIndex =i
        for j in range (i+1,len(lyst)):
            if (lyst[j]<lyst[minIndex]):
                minIndex=j
        if minIndex != i:
            lyst[i],lyst[minIndex]=lyst[minIndex],lyst[i]
    print("selectionSort:",lyst)

冒泡排序

這個就不多說了吧,比較交換,小頭冒泡或者大頭冒泡

def bubbleSort(lyst):
    for i in range (len(lyst)):
        for j in range(i+1,len(lyst)):
            if lyst[j]<lyst[i]:
                lyst[i],lyst[j]=lyst[j],lyst[i]
    print("bubbleSort:",lyst)

優化:如果原本要排序的列表即爲有序列表,則添加一個bool變量用做判斷,如無交換則直接return

#冒泡排序的優化在於加上flag bool變量後,如果爲有序序列,則在
def bubbleSort_improved(lyst):
    swapped=False
    for i in range (len(lyst)):
        for j in range (i+1,len(lyst)):
            if lyst[j]<lyst[i]:
                lyst[i],lyst[j]=lyst[j],lyst[i]
                swapped = True
        #兩層循環,在內層循環比較完後,交換變量swapped仍未發生改變,則直接輸出後return
        if not swapped:
            print("bubbleSort_improved:", lyst)
            return
    print("bubbleSort_improved:",lyst)

插入排序

def insertionSort_improved(lyst):
    for i in range (1,len(lyst)):
        itemToInsert=lyst[i]
        # 利用j的自減來做insertIndex的定位,與break進行配合使用
        j=i-1
        while j >=0 :
            if itemToInsert < lyst[j]:
                lyst[j+1]=lyst[j]
            else:
                break
        lyst[j+1]=itemToInsert
    print("insertionSort_improved:",lyst)

快速排序

lyst=[8,7,3,1,2,3,6,0,12,7]
a=deepcopy(lyst)
#快速排序的基本思想爲:
"""兩個哨兵變量,一個pivot,j--,i++,ij相碰時將lyst[i]與pivot進行對調"""
"""需要把list作爲一個接口參數,不然deecopy的引用參數無法傳入,直接傳入lyst的引用,會修改原始的lyst變量"""
def quickSort(lyst,left,right):
    #需要加上left和right的判斷,不然會超過最大迭代次數,導致棧內存溢出
    if left>right:return
    temp=lyst[left]
    i,j=left,right
    while(i<j):
        while (lyst[j]>=temp and i<j):j -=1
        while (lyst[i]<=temp and i<j):i +=1
        if (i<j):
            lyst[j],lyst[i]=lyst[i],lyst[j]
    lyst[i],lyst[left]=lyst[left],lyst[i]
    quickSort(lyst,left,i-1)
    quickSort(lyst,i+1,right)
def print_quicksort(lyst):
    quickSort(lyst,0,len(lyst)-1)
    print("quickSort:",lyst)
print_quicksort(a)
print("initial list:",lyst)

歸併排序

"""快排與合併排序的基礎思想都是遞歸。對於合併排序每一次都拆成了兩個子序列,直到最後兩個子序列的長度均爲1,"""
def mergeSort(lyst):
    if len(lyst)==1:
        return lyst
    #取拆分的中間位置,拆分成左右兩個子串
    mid = len(lyst)//2
    left=lyst[:mid]
    right=lyst[mid:]
    ll = mergeSort(left)
    rl = mergeSort(right)
    return merge(ll,rl)

#每次取小數放入新開闢的列表空間
#左右子序列進行比較,比較完成後會留下對應的需要加合的left和right序列
def merge(left,right):
    res=[]
    while len(left)>0 and len(right)>0:
        if left[0] <= right[0]:
            res.append(left.pop(0))
        else:
            res.append(right.pop(0))
    res += left
    res += right
    return res
print("mergeSort:",mergeSort(lyst))

堆排序

https://blog.csdn.net/weixin_42348333/article/details/80991081

'''堆排序'''
'''1.從下至上,從右至左,對每個節點進行調整,以得到一個大頂堆'''
'''2.首尾互換,尾部元素已是有序序列,堆元素個數減1,此部分仍爲無序序列,繼續調整'''
 
def big_endian(lyst,start,end):
    root = start
    while True:
        child = root * 2 + 1
        if child > end:
            break
        if child+1 <= end and lyst[child] < lyst[child+1]:
            child += 1
        if lyst[root] < lyst[child]:
            lyst[root], lyst[child] = lyst[child], lyst[root]
            root = child
        else:
            break
 
def heap_sort(lyst):
    first=len(lyst) // 2 - 1
    for start in range (first, -1, -1):
        big_endian(lyst, start, len(lyst)-1)
    for end in range (len(lyst)-1, 0, -1):
        lyst[0], lyst[end] = lyst[end], lyst[0]
        big_endian(lyst, 0, end-1)
 
l = [3, 1, 4, 9, 6, 7, 5, 8, 2, 10]
print (l)
heap_sort(l)
print (l)

 

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