算法導論學習之——排序

第二次看算法導論,感覺對這本書的精髓有了更進一步的掌握,在此,把我認爲比較重要的排序算法做一個總結,歡迎大家批評指正!

排序算法從大的概念分爲比較排序和非比較排序,

比較排序包括:合併排序、堆排序、快速排序

非比較排序: 計數排序、桶排序、基數排序

一、插入排序:

1、簡單介紹:插入排序作爲最基本的入門排序,算法思想最簡單,最容易實現。

該算法是一個就地排序算法,思想是:將數組A中的元素A[1......n]依此插入到已經拍好序的sequenceA中。

2、時間複雜度: best: O(n)      average: O(n^2)     worst: O(n^2)

3、空間複雜度: O(1)

4、插入排序的數據結構

INSERTION-SORT(A)
    for j <- 2 to length[A]
    do key <- A[j]
        # Insert A[j] into the sorted sequence A[1...j-1].
        i <- j-1
        while i>0 and A[i]>key
            do A[i+1] <- A[i]
                i <- i-1
        A[i+1] <- key

4、python實現插入排序代碼:

'''
    insert_sort
    author: fuhongyu
    time: 2018-07-27
    time compliexity:O(n^2)
    objective: 10 minutes
'''
def inser_sort(lists):
    for i in range(1,len(lists)):
        key = lists[i]
        j = i-1
        # insert lists[j] into sequence lists
        while j >= 0:
            if lists[j] > key:
                lists[j+1] = lists[j]
                lists[j] = key
            j -= 1
    return lists

二、合併排序:

1、簡單介紹:合併排序採取了分治法的思想,在每一層遞歸上都有三個步驟:<1>分解 <2>解決 <3> 合併

2、時間複雜度:best: O(n*logn)      average: O(n*logn)      worst: O(n*logn)

3、空間複雜度:O(n)

4、合併排序算法數據結構:

MERGE_SORT(A, p, r)
    if p < r
        then q <- (p+r)/2  # 取下限
           MERGE_SORT(A, p, q) 
           MERGE_SORT(A, q+1, r)
           MERGE(A, p, q, r)

5、python實現合併排序算法代碼:

'''
    merge_sort
    author: fuhongyu
    time: 2018-07-27
    time complexity: O(n^2)
    objective:15 minutes
    
''' 
def merge(a ,b):#  合併兩個list
    i = 0
    j = 0
    result = []
    while i<len(a) and j <len(b):
        if a[i] < b[j]:
            result.append(a[i])
            i += 1
        else:
            result.append(b[j])
            j += 1
    if i == len(a):
        for i in b[j:]:
            result.append(i)
    else:
        for i in a[i:]:
            result.append(i)
    return result


def merge_sort(lists): 
    if len(lists) <= 1:
        return lists
    middle = len(lists)//2
    left = merge_sort(lists[:middle])
    right = merge_sort(lists[middle:])
    return merge(left, right)

測試排序函數:

lists = [3,4,2,6,4,8,3,0,20,34,1,4,56,3]
merge_sort(lists)

6、補充:歸併算法,歸即遞歸,並即合併。該算法運行速度很快,但因爲是遞歸算法,故對CPU消耗很大

三、堆排序:

1、簡單介紹:像合併排序而不像插入排序,堆排序的運行時間是O(n*logn)。像插入排序而不像合併排序,他是一種原地排序算法,在任何時候,數組中只有常數個元素存儲在輸入數組以外。這樣,堆排序就把上述兩種排序的算法的優點結合起來了。

2、時間複雜度: best: O(n*logn)      average: O(n*logn)      worst: O(n*logn)

3、空間複雜度:O(1)

4、算法說明:堆排序過程主要分爲三步:

      1)保持堆的性質:將堆調整爲最大堆:MAX-HEAPIFY(A, i),使i爲根的子樹稱爲最大堆。

      2)建堆: BUILD-MAX-HEAPIFY :將一個數組A[1...n]變成一個最大堆。

      3)堆排序算法:HEAPSORT(A) :  將數組A進行排序

5、python實現代碼如下:

'''
    function:heap sort 
    author: fuhongyu
    time: 2018-07-28
    completion:15 minutes
    time complecity:O(n*logn)
'''
def max_heap(lists, i, size):
    lchild = 2*i 
    rchild = 2*i+1
    max = i
    if lchild < size and lists[lchild] > lists[max]:
        max = lchild
    if rchild < size and lists[rchild] > lists[max]:
        max = rchild
    if max != i:
        lists[i] , lists[max] = lists[max], lists[i]
        max_heap(lists, max, size)

def build_heap( lists):
    size = len(lists)
    for i in range(0, size//2)[::-1]:
        max_heap(lists, i, size)
    return lists

def heap_sort( lists):
    size = len(lists)
    lists = build_heap(lists)
    print(lists)
    for i in range(0, size)[::-1]:
        lists[i], lists[0] = lists[0], lists[i]
        max_heap(lists, 0 ,i)
    print(lists)

測試上面的程序:

lists = [4,1,3,2,16,9,10,14,8,7]
heap_sort(lists)

6、應用:

       雖然堆排序算法是一個很漂亮的算法,但在實際中,快速排序的一個好的實現往往優於堆排序。儘管這樣,堆數據結構還是有很大的用處。一個很常見的應用就是:作爲高效的優先級隊列,包括最大優先級隊列和最小優先級隊列,分別對應最大堆和最小堆。

一個堆可以在O(lgn)時間內,支持大小爲n的集合上的任意優先隊列的操作。

四、快速排序:

接下來要講的快速排序通常情況下,是用於排序的最佳的實用選擇。這是因爲其平均性能相當好:期望的運行時間爲O(nlogn),且O(nlogn)記號中隱藏的常數因子很小。另外,它還能夠進行就地排序,在虛存環境中也能很好地工作。接下來我們便來好好了解一下快速排序的思想。

1、時間複雜度: best: O(n*logn)      average: O(n*logn)      worst: O(n^2)

2、空間複雜度: O(logn)

3、算法描述:

像合併排序一樣,快速排序也是基於分支模式的,主要分爲以下三個步驟:分解、解決、合併

4、快速排序的數據結構:

QUICKSORT(A, p, r)
    if p<r
        then q <- PARTITION(A, p, r)
            QUICKSORT(A, p, q-1)
            QUICKSORT(A, q+1, r)

爲排序一個完整的數組A,最初的調用是QUICKSORT(A, 1, length(A))

快速排序算法的關鍵是PARTITION過程,它對子數組A[p...r]進行就地重排:

PARTITION(A,p, r)
    x <- A[r]
    i <- p-1
    for j <- p to r-1
        do if A[j]<=x
            then i <- i+1
                exchange A[i] <-> A[j]
    exchange A[i+1] <-> A[r]
    return i+1

5、python實現快速排序代碼:

'''
    quick_sort
    author: fuhongyu
    time: 2018-07-27
    time complecity: O(nlog(n))
    object:15 minutes
'''

def quick_sort(array, l, r):
    if l < r:
        q = partition(array, l, r)
        quick_sort(array, l, q - 1)
        quick_sort(array, q + 1, r)
    return array
 
def partition(array, l, r):
    x = array[r]
    i = l - 1
    for j in range(l, r):
        if array[j] <= x:
            i += 1
            array[i], array[j] = array[j], array[i]
    array[i + 1], array[r] = array[r], array[i+1]
    return i + 1

測試快速排序代碼:

lists = [3,5,1,2,7]
quick_sort(lists, 0, len(lists)-1)

五、冒泡排序:

1、簡單說明:冒泡排序的實現非常簡單,時間複雜度大,但是作爲經典的排序算法還是值得一提的。

2、python 實現冒泡排序算法代碼:

'''  
     bubbling_sort
     author: fuhongyu
     time: 2018年7月27日
     時間複雜度: n^2
     目標:5 minutes

'''
def bubblesort(lists):
    for i in range(len(lists)-1):
        for j in range(i+1 , len(lists)):
            if lists[i] > lists[j]:
                temp = lists[i]
                lists[i] = lists[j]
                lists[j] = temp
    return lists

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