1. 程式人生 > 其它 >基礎演算法之排序

基礎演算法之排序

前言:

冒泡,選擇:使用了普通雙指標法

插入,快速,歸併:使用了二分法,遞迴

氣泡排序

原理:不斷比較相鄰兩個數得大小,把較大的數交換到靠後的位置

def bubbleSort(iList):
    '''氣泡排序 '''
    if len(iList) <= 1:
        return iList
    for i in range(1, len(iList)):
        for j in range(0, len(iList)-i): 
            # 原理:不斷比較相鄰兩個數得大小,把較大的數交換到靠後的位置
            if iList[j] >= iList[j+1]: #比較相鄰兩數的大小
                iList[j], iList[j+1] = iList[j+1], iList[j] #將大數交換到靠後的位置
        # print("第 %d 輪排序結果:" %i, end="")
        # print(iList)
    return iList

選擇排序

原理

 # 藉助了min函式和列表切片
 # 不斷從列表中選出最大或者最小的數,放到合適的位置
 # 然後再丟擲這個數的子數列中找最大(最小)的數,並放到合適的位置(採用覆蓋列表值<==這個經常再排序中用到)
 # 直到子數列為空

程式碼

def selectionSort(iList):
    if len(iList) <= 1:
        return iList
    for i in range(0, len(iList)-1):
        # 藉助了min函式和列表切片
        # 不斷從列表中選出最大或者最小的數,放到合適的位置
        # 然後再丟擲這個數的子數列中找最大(最小)的數,並放到合適的位置(採用覆蓋列表值<==這個經常再排序中用到)
        # 直到子數列為空
        if iList[i] != min(iList[i:]): #使用min函式找到剩餘數列中最小的那個數
            minIndex = iList.index(min(iList[i:])) #minIndex是最小數的序號(下標)
            iList[i], iList[minIndex] = iList[minIndex], iList[i]
        # print("第 %d 輪排序結果:" %(i+1), end="")
        # print(iList)
    return iList

插入排序

# 原理:將數列分成兩部分,第一個時left部分,其餘的數為right部分
        # 將right部分逐一取出,插入left部分中合適的位置
        # 當left部分為空時,left部分就成了一個有序數列

程式碼

def insertionSort(iList):
    if len(iList) <= 1:
        return iList
    for right in range(1, len(iList)):
        # 原理:將數列分成兩部分,第一個時left部分,其餘的數為right部分
        # 將right部分逐一取出,插入left部分中合適的位置
        # 當left部分為空時,left部分就成了一個有序數列
        target = iList[right]
        for left in range(0, right):
            if target <= iList[left]:
                # 下面這句為什麼往後移一位沒弄懂
                iList[left+1:right+1] = iList[left:right] # 比target大的left部分整體後移一位
                iList[left] = target  # 使用Python的切片賦值
                break
        # print("第 %d 輪排序結果:" %(right), end="")
        # print(iList)
    return iList

歸併排序

原理

原理:無限的的把左右序列變成兩個子數列,然後將左右兩個子數列排序完畢後(這裡的子數列分成了1個單位)
    # 在合併到一起就完成了一個有序序列

程式碼

def mergeSort(iList):
    # 原理:無限的的把左右序列變成兩個子數列,然後將左右兩個子數列排序完畢後(這裡的子數列分成了1個單位)
    # 在合併到一起就完成了一個有序序列
    if len(iList) <= 1:
        return iList
    # 列表指數為基數時拆分列表
    middle = len(iList)//2
    left, right = iList[0:middle], iList[middle:]
    return mergeList(mergeSort(left), mergeSort(right))

def mergeList(left, right):
    mList = []
    while left and right:
        if left[0] >= right[0]:
            mList.append(right.pop(0))
        else:
            mList.append(left.pop(0))
    # 下面沒搞懂 刪除的話  就是錯誤排序      
    # 下面的left,right為真,取出該數列中的第一個元素
    while left:
        mList.append(left.pop(0))
    while right:
        mList.append(right.pop(0))
    return mList

快速排序

原理

原理:以列表中的任意一個數為基準,將列表分成左右兩個字列表
        # 左列表的數要比基數小
        # 右列表的數要比基數大
        # 然後繼續把左子列表,右子列表按同樣的方式分解,比較,直到分無可分為止
        # 一般的話基數為索引第一個

程式碼

def quickSort(iList):
    if len(iList) <= 1:
        return iList
    left = []
    right = []
    for i in iList[1:]: # 這裡不設定0的話,iList的要為多少呢[],難道說只要比基準數大1;不設定0的話,設定1就會比0少一半得出的資料;
        # 原理:以列表中的任意一個數為基準,將列表分成左右兩個字列表
        # 左列表的數要比基數小
        # 右列表的數要比基數大
        # 然後繼續把左子列表,右子列表按同樣的方式分解,比較,直到分無可分為止
        # 一般的話基數為索引第一個
        if i <= iList[0]:
            left.append(i)
        else:
            right.append(i)
    return quickSort(left) + [iList[0]] + quickSort(right) # 這裡遞迴

計數排序

原理

原理:在一個相同的索引i下,求出有多少個數比i小,然後再把該i索引的值寫入多少個數對應的索引值

程式碼

def countingSort(iList):
    if len(iList) <= 1:
        return iList
    iLen = len(iList)
    rList = [None]*iLen
    for i in range(iLen): # 好經典
        small = 0 #比基數小的
        same = 0 #與基數相等的
        for j in range(iLen):
            if iList[j] < iList[i]: # 這個是判斷出有多少個數比身為i索引時小
                small += 1 # 但這個數字加不會越來越多麼,在一個迴圈中
            elif iList[j] == iList[i]: #相同的數
                same += 1
        for k in range(small, small+same): # 這個就是怎麼把對應的數插在對應索引下麼
            # 原理:在一個相同的索引i下,求出有多少個數比i小,然後再把該i索引的值寫入多少個數對應的索引值
            rList[k] = iList[i] # 這個i有點狠,還在i的迴圈裡
    return rList

沒搞懂的地方:

插入排序

 iList[left+1:right+1] = iList[left:right] # 比target大的left部分整體後移一位

歸併排序

# 下面沒搞懂 刪除的話  就是錯誤排序      
    # 下面的left,right為真,取出該數列中的第一個元素
    while left:
        mList.append(left.pop(0))
    while right:
        mList.append(right.pop(0))
    return mList

知識點:

 # 列表指數為奇數時拆分列表
    middle = len(iList)//2
    left, right = iList[0:middle], iList[middle:]
# 建立雙指標
for i in range(1, len(iList)):
        for j in range(0, len(iList)-i): 
# 遞迴呼叫本身函式
def mergeSort(iList):
    # 原理:無限的的把左右序列變成兩個子數列,然後將左右兩個子數列排序完畢後(這裡的子數列分成了1個單位)
    # 在合併到一起就完成了一個有序序列
    if len(iList) <= 1:
        return iList
    # 列表指數為奇數時拆分列表
    middle = len(iList)//2
    left, right = iList[0:middle], iList[middle:]
    return mergeList(mergeSort(left), mergeSort(right))
努力拼搏吧,不要害怕,不要去規劃,不要迷茫。但你一定要在路上一直的走下去,儘管可能停滯不前,但也要走。