排序算法小結

        排序算法一直以來是個人心病,此次爲了搞定這塊內容,進行了一次系統的學習,結合大神的講解以及我的的總結,梳理了如下的解決方案,順便給出相關的遷移問題以及解決方案。python

概況:算法

排序通常分爲選擇排序和插入排序這兩大類,其他排序都是在這兩塊上的優化和深刻。api

這裏不得不提到時間複雜度,雖然爲O(n*2),但是在特定的場合下,插入排序仍是比較快的,尤爲是在近乎有序的狀況下,通常在數據量比較小而接近的dom

狀況下使用比較好。函數

插入排序衍生出冒泡排序和希爾排序學習

高級排序(O(nlogn)):測試

歸併排序、快速排序、雙路/三路快速排序、堆排序優化

下面給出相關的代碼實例(python格式):ui

選擇排序:spa

def selectSort(arr):
    """
        選擇排序
    """
    for i in range(0,len(arr)):
        # 在[i,n)中選擇最小的索引
        min_index = i
        for j in range(i+1,len(arr)):
            if arr[j] < arr[min_index]:
                min_index = j
        # 交換i與min_index的位置
        # swap(arr[i], arr[min_index]) python中不須要使用這個,內存空間中局部變量無效
        arr[i], arr[min_index] = arr[min_index], arr[i]

插入排序:

def insertSort(arr):
    """
        插入排序
    """
    for i in range(1, len(arr)):
        # 選擇arr[i]的位置
        a = arr[i]
        j = i
        for j in range(1, i+1)[::-1]:
            # if arr[j-1] > arr[j]:
            #     arr[j-1], arr[j] = arr[j], arr[j-1]
            if arr[j-1] > a:
                arr[j] = arr[j-1]
            else:
                break
        arr[j] = a

 快速排序:

def _parition(arr, s, e):
    """
        找拆分位置
        arr[s...index -1]<arr[index] arr[index+1....e]> arr[index]
    """
    #初始第一個
    base = arr[s]
    j = s
    #使得 arr[i+1....j-1]< base and arr[j+1....e]>base
    for i in range(s+1, e+1):
        if arr[i] < base:
            arr[j+1], arr[i] = arr[i], arr[j+1]
            j += 1
    arr[s], arr[j] = arr[j], arr[s]
    return j



def _quickSort(arr, l, r, n):
    """
        進行快排
    """
    if r < l:
        return
    index = _parition(arr, l, r)
    if index == n:
        return index

    _quickSort(arr, l, index-1, n)
    _quickSort(arr, index+1, r, n)


def quickSort(arr, n):
    """
        快速排序
    """
    return _quickSort(arr, 0, len(arr)-1, n)

  歸併排序:

def __merge_sort(arr, s, mid, e):
    """
        歸併arr[s...mid] arr[mid+1....e]
    """
    #初始化歸併空間
    merge_arr = [0] * (e-s+1)
    #賦值
    for i in range(s, e+1):
        merge_arr[i-s] = arr[i]

    i = s
    j = mid+1
    #歸併
    for k in range(s, e+1):
        if i > mid:
            arr[k] = merge_arr[j-s]
            j += 1
        elif j > e:
            arr[k] = merge_arr[i-s]
            i += 1
        elif merge_arr[i-s] <merge_arr[j-s]:
            arr[k] = merge_arr[i-s]
            i += 1
        else:
            arr[k] = merge_arr[j-s]
            j += 1



def _mergeSort(arr, s, e):

    if s >= e:
        return
    #改進數據量小的時候,用插入排序
    if e-s <20:
        insertSort(arr)
        return
    #中間位置
    mid = s + (e-s)//2
    _mergeSort(arr, s, mid)
    _mergeSort(arr, mid+1, e)
    if arr[mid] < arr[mid+1]:
        __merge_sort(arr, s, mid, e)


def mergeSort(arr):
    """
        歸併排序
    """
    _mergeSort(arr, 0, len(arr)-1)  

堆排序:

def MAX_Heapify(heap, HeapSize, root):
    left = 2*root + 1
    right = left + 1
    larger = root
    if left < HeapSize and heap[larger] < heap[left]:
        larger = left
    if right < HeapSize and heap[larger] < heap[right]:
        larger = right
    if larger != root:#若是作了堆調整則larger的值等於左節點或者右節點的,這個時候作對調值操做
        heap[larger],heap[root] = heap[root],heap[larger]
        MAX_Heapify(heap, HeapSize, larger)


def Build_MAX_Heap(heap):
    HeapSize = len(heap)#將堆的長度當獨拿出來方便
    for i in range((HeapSize -2)//2,-1,-1):#從後往前出數
        MAX_Heapify(heap,HeapSize,i)


def heapSort(arr):
    Build_MAX_Heap(arr)
    for i in range(len(arr)-1,-1,-1):
        arr[0],arr[i] = arr[i],arr[0]
        MAX_Heapify(arr, i, 0)
    return arr

如下是隨機生成測試數據和計算排序時長的方式:

def generArr(l, r, n):

    arr = [0] * n
    for i in range(0, n):
        arr[i] = random.randint(l,n)
    return arr


def countTime(arr, func = None):
    """
        計算時長
    """
    start = time.time()
    func(arr)
    end = time.time()
    print(func.__name__, '時長{}s'.format(round((end-start), 5)))

  計算結果以下:

def main():
    """
        主函數
    """
    arr = generArr(0, 100, 10000)
    arrs = generArr(0, 100, 10000)
    countTime(arr, mergeSort)
    countTime(arrs, insertSort)
if __name__ == '__main__':
    main()


D:\anacond\python.exe E:/cources_python/data_structure/algorithm/sort_demo.py
mergeSort 時長15.77121s
insertSort 時長7.39828s

Process finished with exit code 0
相關文章
相關標籤/搜索