首頁  >  文章  >  後端開發  >  歸併排序中對小數組採用插入排序

歸併排序中對小數組採用插入排序

巴扎黑
巴扎黑原創
2016-12-08 11:33:161496瀏覽

純歸併排序的複雜度為: O(nlgn),而純插入排序的時間複雜度為:O(n^2)。資料量很大的時候採用歸併排序

但是在n較小的時候插入排序可能運行的會更快點。因此在歸併排序中當子問題變得足夠小時,採用插入排序來使得遞歸的葉子變粗可以加快排序速度。那麼這個夠小到底怎麼去衡量呢? 請看下面:

這麼幾個我不證明了,比較簡單:

A,插入排序最壞情況下可以在O(nk)時間內排序每個長度為k的n/k個子列表

B ,在最壞情況下可在O(nlg(n/k))的時間內合併這些子表

C,修訂後的演算法的最壞情況運行時間複雜度是O(nk + nlg(n/k ))

那麼,O(nk+nlg(n/k))=O(nlgn).只能最大是k=O(lgn).等式左邊中第一項是高階項。 k如果大於lgn,則比歸併排序複雜度大了。左邊可以寫成nk+nlgn-nlgk,k等於lgn時,就是2nlgn-nlglgn.忽略恆定係數,則與歸併排序是一樣的。

最後結論:  k

from at003_insertsort import insertSort
from math import log
__author__ = 'Xiong Neng'
def mergeSort(seq):
    mergeSortRange(seq, 0, len(seq) - 1, log(len(seq)) - 1)
def mergeOrderedSeq(seq, left, middle, right):
    """
    seq: 待排序序列
    left <= middle <= right
    子数组seq[left..middle]和seq[middle+1..right]都是排好序的
    该排序的时间复杂度为O(n)
    """
    tempSeq = []
    i = left
    j = middle + 1
    while i <= middle and j <= right:
        if seq[i] <= seq[j]:
            tempSeq.append(seq[i])
            i += 1
        else:
            tempSeq.append(seq[j])
            j += 1
    if i <= middle:
        tempSeq.extend(seq[i:middle + 1])
    else:
        tempSeq.extend(seq[j:right + 1])
    seq[left:right + 1] = tempSeq[:]
def mergeSortRange(seq, start, end, threshold):
    """
    归并排序一个序列的子序列
    start: 子序列的start下标
    end: 子序列的end下标
    threshold: 待排序长度低于这个值,就采用插入排序
    """
    if end - start < threshold:
        tempSeq = seq[start: end + 1]
        insertSort(tempSeq)
        seq[start: end + 1] = tempSeq[:]
    elif start < end:  # 如果start >= end就终止递归调用
        middle = (start + end) / 2
        mergeSortRange(seq, start, middle, threshold)  # 排好左边的一半
        mergeSortRange(seq, middle + 1, end, threshold)  # 再排好右边的一半
        mergeOrderedSeq(seq, start, middle, end)  # 最后合并排序结果
if __name__ == &#39;__main__&#39;:
    aa = [4, 2, 5, 1, 6, 3, 7, 9, 8]
    mergeSort(aa)
    print(aa)


陳述:
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn