【算法學習筆記三】排序算法及有關證明

一.選擇排序(Selection Sort)

令A[1...n]爲一個n個元素的數組,首先找到最小的元素,將其存放在A[1]中,然後找到剩下的n-1個元素中的最小元素,將其存放在A[2]中,重複此過程直至找到第二大的元素,並將其存放在A[n-1]中。

元素交換次數0~n-1;選擇排序的元素比較次數爲\sum_{i=1}^{n-1}(n-i)=\frac{n(n-1)}{2};元素賦值次數0~3(n-1)。

    for i <- 1 to n-1
        k <- i
        for j <- i+1 to n {Find the ith smallest element}
            if A[j]<A[k] then k <- j
        end for
        if k≠i then interchange A[i] and A[k]
    end for

二.插入排序(Insertion Sort)

從大小爲1的子數組A[1]開始,它自然是有序的,將A[2]插入到A[1]的前面或者後面,這取決於A[2]比其大還是小。繼續這一過程,在第i次執行中,要將A[i]插入到已排序的子數組A[1...i-1]中的合適位置上,,依次掃描序號從i-1到1的元素,每次都將A[i]和當前位置的元素比較。在掃描的每一步,元素都被移到序號更高的一個位置,這種執行比較和移位的掃描直到找到一個小於等於A[i]的元素或者前面所有的元素都掃描過,A[i]被插入到合適的位置。

執行插入算法的元素比較次數在n-1到n(n-1)/2之間。元素賦值次數等於元素比較次數加上n-1。

    for i <- 2 to n
        x <- A[i]
        j <- i-1
        while (j>0) and (A[j]>x)
            A[j+1] <- A[j]
            j <- j-1
        end while
        A[j+1] <- x
    endfor

三.自底向上合併排序(BottomUpMergeSort)

令A爲需要排序的n個元素的數組,首先合併成$\lfloor n/2 \rfloor$個連續元素對,如果剩餘一個元素,就讓它進入下一輪迭代。然後合併成$\lfloor n/4 \rfloor$個連續的大小爲4的排序序列。如果剩餘一或兩個元素,那麼它們將進入下一次迭代;如果剩餘三個元素,將兩個(已排序的)元素和另一個元素合併成一個3元素的排序序列。繼續這一過程,在第j次迭代中,合併成$\lfloor n/2^j \rfloor$個大小爲2^j的排序序列。如果剩餘k個剩餘元素,$1 \leq k \leq {}2^{j-1}}}$,則將它們放在下一次合併中;${2^{j-1}} \textless k \textless {2^{j}}$,則將它們合併,形成一個大小爲k的排序序列。

 Merge合併

MERGE合併
輸入:數組A[1...m]和它的三個索引p,q,r,1≤p≤q<r≤m,兩個子數組A[p...q]和A[q+1...r]各自按升序排列
輸出:合併兩個子數組A[p...q]和A[q+1...r]的數組A[p...r]
B[p...r]是個輔助數組
 
    s <- p, t <- q+1, k <- p
    while s≤q and t≤r
       if A[s]≤A[t] then
           B[k] <- A[s]
           s <- s+1
       else
            B[k] <- A[t]
            t <- t+1
       end if
       k <- k+1
    endwhile
    if s=q+1 then B[k..r] <- A[t..r]
    else B[k..r] <- A[s..q]
    endif
    A[p..r] <- B[p..r]

 執行算法MERGE將兩個大小分別爲n_1和n_2n_2的非空數組合併成一個大小爲n=n_1+n_2的排序數組,當$n_1 \leq n_2$時,元素比較次數在n_1~n-1之間。

 BottomUpSort算法

    t <- 1
    while t<n
          #s爲當前合併元素組中元素個數
          s <- t, t <- 2s, i <- 0 
          while i+t≤n
              #i+1,i+s,i+t用來定義兩個要排序的序列的邊界
              MERGE(A, i+1, i+s, i+t)
              i <- i+t
          end while
          #如果剩餘元素即(n-i)大於s,就要在大小爲s的學列和剩餘元素之間在進行一次排序
          if i+s<n then MERGE(A, i+1, i+s, n)
    endwhile

用算法對n個元素的數組進行排序,當n爲2的冪時,元素比較次數在(nlogn)/2到(nlogn-n+1)之間。執行該算法的元素賦值次數爲2nlogn。

證明過程:

令n=2^k,while循環了logn次;

第j次while循環,兩個大小爲爲2^{j-1}的子序列的合併操作共有n/2^j,則第j次迭代中元素比較的次數在(n/2^j)/2^{j-1}(n/2^j)/(2^j-1)

比較次數最少爲:\sum_{j=1}^{logn}(n/2^j)2^{j-1}=\sum_{j=1}^{logn}n/2=nlogn/2

最多爲:\sum_{j=1}^{logn}(n/2^j)(2^{j}-1)=\sum_{j=1}^{logn}(n-n/2^j)=nlogn-n\frac{\frac{1}{2}(1-\frac{1}{2^{logn}})}{1-\frac{1}{2}}=nlogn-n+1

每輪2n次賦值,共2nlogn次賦值操作。

 

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