1. 程式人生 > >【演算法 in python】排序演算法

【演算法 in python】排序演算法

 

 

1. 氣泡排序

def bubbleSort(arr):
    for i in range(len(arr)-1):
        for j in range(len(arr)-1-i):
            if arr[j] > arr[j+1]:
                arr[j],arr[j+1] = arr[j+1], arr[j]
    return arr

 

2. 選擇排序

def selectSort(arr):
    for i in range(len(arr)):
        minindex = i
        for j in range(i+1, len(arr)):
            if arr[j] < arr[minindex]:
                minindex = j
        arr[i], arr[minindex] = arr[minindex], arr[i]
    return arr

3. 插入排序

#插入排序
def insertSort(arr):
    for i in range(1, len(arr)):
        #前i個已排序
        pre = i-1
        cur = arr[i]
        while pre >=0 and cur < arr[pre]:
            arr[pre+1] = arr[pre]
            pre -= 1
        arr[pre+1] = cur
    return arr

4. 希爾排序

def shellSort(A):
    # write code here
    step = len(A)/2
    while step > 0:
        for i in range(step, n):
            cur = A[i]
            pre = i - step
            while pre >= 0 and A[pre] > cur:
                A[pre+step] = A[pre]
                pre -= step
            A[pre + step] = cur
        step = step/2
    return A

5. 快速排序

# 快排遞迴
def quickSort1(arr, left, right):
    if left < right:
        index = partition(arr, left, right)
        quickSort1(arr, left, index - 1)
        quickSort1(arr, index + 1, right)
        return arr

#快排非遞迴
def quickSort2(arr, left, right):
    if left >= right:
        return -1
    stack = [right, left]
    while len(stack) > 0:
        l = stack.pop()
        r = stack.pop()
        if l < r:
            index = partition(arr, l, r)
            stack.append(index - 1)
            stack.append(l)
            stack.append(r)
            stack.append(index + 1)
    return arr

def partition(arr, left, right):
    key = right
    while left < right:
        while left < right and arr[left] <= arr[key]:
            left += 1
        while left < right and arr[right] >= arr[key]:
            right -= 1
        arr[left], arr[right] = arr[right], arr[left]
    arr[key], arr[left] = arr[left], arr[key]
    return left

 

6. 歸併排序

#歸併排序(分治法)
def mergeSort(arr, left, right):
    if left >= right:
        return
    mid = int((left+right)/2)
    mergeSort(arr, left, mid)
    mergeSort(arr, mid+1,right)
    merge(arr, left, mid, right)
    return arr

def merge(arr, left, mid, right):
    temp = []
    i = left
    j =  mid + 1
    while i <= mid and j <= right:
        if arr[i] < arr[j]:
            temp.append(arr[i])
            i+=1
        else:
            temp.append(arr[j])
            j+=1
    if i <= mid:
        temp += [item for item in arr[i:mid+1]]
    if j <= right:
        temp += [item for item in arr[j:right+1]]
    arr[left:right+1] = temp

7. 堆排序

參考:https://www.cnblogs.com/chengxiao/p/6129630.html

堆 == 完全二叉樹

大頂堆: 父>=子, arr[i] >= arr[2*i+1], arr[i] >= arr[2*i+2]

小頂堆:父<=子,arr[i] <= arr[2*i+1], arr[i] <= arr[2*i+2]

最後一個非葉子節點:

index = length//2 -1

步驟:

1. 給定無序序列,構建大頂堆(升序)或小頂堆(降序);

2. 將堆頂元素與序列末尾元素交換,使得最大值放到最後;

3. 在新的無序序列(除去最後一個元素)重複步驟1,2

class HeapSort:
    def heapSort(self, arr, n):
        # 給定隨機二叉樹,從最後一個非葉子節點開始,對每個父節點,調整大頂堆。最後形成初始化的大頂堆。
        for i in range(len(arr) // 2 - 1, -1, -1):
            self.adjustHeap(arr, i, len(arr))
        # 交換堆頂元素與末尾元素完成一次排序,然後調整剩餘堆結構
        for j in range(len(arr) - 1, 0, -1):
            arr[0], arr[j] = arr[j], arr[0]  # 堆頂元素與末尾元素交換
            self.adjustHeap(arr, 0, j)  # 排除已排序的節點,重新調整堆
        return arr
    
    # 對二叉樹從start節點到end+1節點,調整堆結構,形成大頂堆,
    def adjustHeap(self, arr, start, end):
        temp = arr[start]
        i = start * 2 + 1  
        #遍歷所有屬於start的子節點,或子子節點,找到最大值放在堆頂
        while i < end:
            #找到比父節點大的子節點,若存在,則交換值
            if i + 1 < end and arr[i] < arr[i + 1]:
                i += 1
            if arr[i] > temp:
                arr[start] = arr[i]
                start = i
                arr[i] = temp
                i = i * 2 + 1
                #若不存在,則退出迴圈
            else:
                break