青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品

羅朝輝(飄飄白云)

關注嵌入式操作系統,移動平臺,圖形開發。-->加微博 ^_^

  C++博客 :: 首頁 :: 新隨筆 :: 聯系 :: 聚合  :: 管理 ::
  85 隨筆 :: 0 文章 :: 169 評論 :: 0 Trackbacks

排序算法之歸并排序   

羅朝輝(http://www.shnenglu.com/kesalin

轉載請注明出處

排序是數據處理中經常使用的一種重要運算,在計算機及其應用系統中,花費在排序上的時間在系統運行時間中占有很大比重,其重要性勿需多言。下文將介紹常用的如下排序方法,對它們進行簡單的分析和比較,并提供 C 語言實現。


所謂排序,就是要將一堆記錄,使之按關鍵字遞增(或遞減)次序排列起來。根據排序所采用的策略,可以分為如下五種:

1、插入排序(直接插入排序、希爾排序)

2、交換排序(冒泡排序、快速排序)

3、選擇排序(直接選擇排序、堆排序)
    4、歸并排序;

5、桶排序(桶排序,基數排序);


---------------------------------------------------------------------------------


前面講了插入排序,交換排序,選擇排序,下面接著來講歸并排序


歸并排序(Merge Sort)是利用"歸并"技術來進行排序。歸并是指將若干個已排序的子文件合并成一個有序的文件。


歸并排序

基本思想:設兩個有序的子序列(相當于輸入序列)放在同一序列中相鄰的位置上:array[low..m],array[m + 1..high],先將它們合并到一個局部的暫存序列 temp (相當于輸出序列)中,待合并完成后將 temp 復制回 array[low..high]中,從而完成排序。


在具體的合并過程中,設置 i,j 和 p 三個指針,其初值分別指向這三個記錄區的起始位置。合并時依次比較 array[i] 和 array[j] 的關鍵字,取關鍵字較小(或較大)的記錄復制到 temp[p] 中,然后將被復制記錄的指針 i 或 j 加 1,以及指向復制位置的指針 p 加 1。重復這一過程直至兩個輸入的子序列有一個已全部復制完畢(不妨稱其為空),此時將另一非空的子序列中剩余記錄依次復制到 array 中即可。


下面是合并過程的 C 代碼實現:
   


void merge(int* array, int low, int mid, int high)
{
    assert(array 
&& low >= 0 && low <= mid && mid <= high);

    
int* temp = (int*)malloc((high - low + 1* sizeof(int));
    
if (!temp) {
        printf(
"Error:out of memory!");
        
return;
    }


    
int i = low;
    
int j = mid + 1;
    
int index = 0;

    
while (i <= mid && j <= high) {
        
if (array[i] <= array[j]) {
            temp[index
++= array[i++];
        }

        
else {
            temp[index
++= array[j++];
        }

    }


    
while (i <= mid) {
        temp[index
++= array[i++];
    }


    
while (j <= high) {
        temp[index
++= array[j++];
    }


    memcpy((
void*)(array + low), (void*)temp, (high - low + 1* sizeof(int)) ;

    free(temp);
}


   歸并排序有兩種實現方法:自底向上和自頂向下。


自底向上方法,也就是常說的二路歸并排序,其基本思想是:第 1 趟排序將長度為 n 的待排序記錄看作 n 個長度為 1 的有序子序列,然后將這些子序列兩兩合并。完成第 1 趟排序之后,將得到 lgn 個長度為 2 的有序子序列(如果 n 為奇數,則最后還有一個長度為 1 的子序列)。第 2 趟排序是在第 1 趟的排序的基礎上,將這 lgn 個長度為 2 的子序列兩兩合并。如此反復,直到最后得到一個長度為n的有序文件為止。從這個排序過程來看,二路歸并排序是從將長度為 1 的子序列排序變化到長度為 n 的有序序列,因而是自底向上的。


下面是二路歸并排序的 C 代碼實現:
   


// 對 [0, length - 1] 做一趟歸并長度為 n  的歸并排序
void merge_pass(int* array, int length, int n)
{
    assert(array 
&& length >= 1 && n >= 1);

    
int i;
    
int sortLength = 2 * n;

    
// 歸并長度為 n 的兩個相鄰子序列
    for(i = 0; i + sortLength - 1 < length; i = i + sortLength) {
        merge(array, i, i 
+ n - 1, i + sortLength - 1);
    }


    
// 若 i + n - 1 < length - 1,則剩余一個子文件輪空,無須歸并。
    
// 尚有兩個子序列,其中后一個長度小于 n, 歸并最后兩個子序列。
    if (length - 1 > i + n - 1{
        merge(array, i, i 
+ n - 1, length - 1);
    }

}


// 用分治法自下向上進行二路歸并排序
//
void merge_sort(int* array, int length)
{
    assert(array 
&& length >= 0);

    
int n;

    
for(n = 1; n < length; n = (n << 1)) {
        merge_pass(array, length, n);
    }

}


   
   自底向上的二路歸并排序算法雖然效率較高,但可讀性較差(循環實現比遞歸實現一般效率都要高些)。下面來看看自上而下的遞歸實現,其可讀性要好得多。自上而下的方法是采用分治法思想,具體排序過程分成三個過程:

(1)分解:將當前區間一分為二,即求分裂點 mid = (low + high)/2

(2)求解:遞歸地對兩個子區間 array[low..mid] 和 array[mid + 1..high] 進行歸并排序;遞歸的終結條件:子區間長度為 1(一個記錄自然有序)。

(3)合并:將已排序的兩個子區間R[low..mid]和R[mid + 1..high]歸并為一個有序的區間 array[low..high]。

  

下面即是自上而下方法的 C 代碼實現:
   


void merge_sort_dc_impl(int* array, int low, int high)
{
    assert(array 
&& low >= 0);

    
int mid;
    
if (low < high) {
        mid 
= (low + high) >> 1;

        merge_sort_dc_impl(array, low, mid);
        merge_sort_dc_impl(array, mid 
+ 1, high);

        merge(array, low, mid, high);
    }

}


// 用分治法自上向下進行排序
void merge_sort_dc(int* array, int length)
{
    assert(array 
&& length >= 0);

    merge_sort_dc_impl(array, 
0, length - 1);
}


   時間復雜度分析:
   對長度為 n 的序列進行 lgn 趟二路歸并,而每一趟歸并的時間復雜度為 O(n),因此歸并排序的平均時間復雜度為 nlgn。


空間復雜度分析:

需要與待排記錄等大的空間來存儲中間變量,因為其空間復雜度為 O(n)。因此,歸并排序肯定就不是就地排序了。


補充:

歸并排序是穩定排序。若歸并排序采用鏈表存儲結構的話,實現起來更加高效。


=======================================================================================

測試:

在前文《排序算法之插入排序》測試代碼的基礎上添加兩行代碼即可:


{"合并排序:自下向上二路歸并", merge_sort}, {"合并排序:自上向下分治", merge_sort_dc},


運行結果如下:


=== 合并排序:自下向上二路歸并 ===

 original: 65 32 49 10 8 72 27 42 18 58 91

   sorted: 8 10 18 27 32 42 49 58 65 72 91


 original: 10 9 8 7 6 5 4 3 2 1 0

   sorted: 0 1 2 3 4 5 6 7 8 9 10



=== 合并排序:自上向下分治 ===

 original: 65 32 49 10 8 72 27 42 18 58 91

   sorted: 8 10 18 27 32 42 49 58 65 72 91


 original: 10 9 8 7 6 5 4 3 2 1 0

   sorted: 0 1 2 3 4 5 6 7 8 9 10


posted on 2011-03-13 15:19 羅朝輝 閱讀(8240) 評論(0)  編輯 收藏 引用 所屬分類: Algorithms
青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品
  • <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>
            欧美视频在线观看免费| 亚洲一区视频在线观看视频| 亚洲欧美日韩一区在线| 欧美一区1区三区3区公司| 欧美片在线播放| 欧美激情一区二区三区在线视频观看 | 亚洲国产成人久久| 亚洲精品久久在线| 国产精品视频999| 在线观看欧美精品| 亚洲精品一区二区三区四区高清| 亚洲第一精品在线| 欧美精品在线视频观看| 欧美成人官网二区| 伊人婷婷久久| 欧美日韩成人网| 亚洲一区二区在线免费观看| 亚洲国产另类久久精品| 欧美日本韩国一区二区三区| 中文在线一区| 国内外成人在线视频| 国产精品亚洲产品| 欧美日韩裸体免费视频| 一区二区三区日韩欧美精品| 亚洲九九九在线观看| 欧美一区二区精品久久911| 在线免费观看日本欧美| 欧美剧在线免费观看网站| 亚洲欧美一区二区在线观看| 亚洲人久久久| 嫩草影视亚洲| 欧美一区二区高清在线观看| 亚洲精选91| 亚洲欧美日韩国产精品 | 亚洲欧美国产77777| 亚洲综合第一| 国产日韩亚洲欧美| 免费毛片一区二区三区久久久| 日韩五码在线| 欧美日韩在线不卡| 91久久精品国产91性色tv| 欧美日韩一区二区欧美激情| 亚洲激情小视频| 欧美激情精品久久久久久蜜臀 | 久久精品国产99国产精品| 欧美日韩精选| 亚洲激情在线| 国产亚洲美州欧州综合国| 亚洲国产国产亚洲一二三| 欧美成人免费全部观看天天性色| 国产精品国产福利国产秒拍| 亚洲国产二区| 国产精品第十页| 久久综合综合久久综合| 好看的av在线不卡观看| 欧美中文字幕在线视频| 亚洲视频精品| 久久精品五月婷婷| 亚洲欧洲精品一区二区三区不卡 | 国产精品久久久久久影视| 久久激情综合网| 亚洲国产视频一区| 久久亚洲私人国产精品va| 农村妇女精品| 在线亚洲观看| 伊人男人综合视频网| 欧美激情一区二区三区蜜桃视频 | 亚洲丝袜av一区| 亚洲视频第一页| 国产精品推荐精品| 老司机久久99久久精品播放免费| 久久精品免费| 亚洲精品在线一区二区| 国产精品日韩欧美一区二区三区| 欧美专区在线| 亚洲天天影视| 久久中文精品| 久久精品亚洲国产奇米99| 亚洲国产欧美日韩精品| 欧美香蕉视频| 快射av在线播放一区| 午夜亚洲福利在线老司机| 亚洲第一视频| 99re视频这里只有精品| 亚洲天堂免费观看| 一区二区三区免费看| 亚洲国产精品久久91精品| 久久久久久自在自线| 午夜精品一区二区三区电影天堂 | 国产精品乱码| 欧美国产日韩一区二区在线观看| 欧美成人日韩| 欧美视频在线看| 国产日韩欧美精品综合| 欧美视频在线不卡| 国产日韩精品视频一区| 一区免费在线| 鲁大师影院一区二区三区| 日韩一区二区高清| 亚洲黄色免费网站| 免费在线观看成人av| 亚洲第一精品电影| 欧美黄免费看| 欧美国产第二页| 一区二区电影免费观看| 99精品视频一区| 久久精品亚洲| 国产精品久久久久一区二区三区共| 国产精品午夜国产小视频| 国内揄拍国内精品少妇国语| 亚洲第一成人在线| 亚洲第一精品影视| 欧美一区二区女人| 久久久久久夜| 99精品欧美一区二区蜜桃免费| 一区二区三区欧美成人| 欧美精品v日韩精品v国产精品 | 国产精品成人午夜| 99精品欧美一区二区三区| 国产精品女同互慰在线看| 亚洲视频综合| 夜夜嗨av色综合久久久综合网| 亚洲一区二区三区免费视频| 欧美日韩福利| 一区二区三区精品视频| 麻豆精品精华液| 久久久国产精品一区| 国产农村妇女精品一区二区| 亚洲级视频在线观看免费1级| 欧美激情一区二区三区在线视频观看 | 日韩视频国产视频| 欧美在线1区| 99热精品在线观看| 国产精品久久久久9999| 亚洲午夜一区二区三区| 欧美专区18| 亚洲免费在线观看视频| 欧美片第1页综合| 久久久久久国产精品mv| 欧美区国产区| 艳女tv在线观看国产一区| 免费亚洲视频| 老牛国产精品一区的观看方式| 亚洲国产日韩欧美| 午夜国产精品视频| 99精品欧美| 美女网站在线免费欧美精品| 女仆av观看一区| 国产精品亚洲综合一区在线观看| 一个人看的www久久| 一区二区三区四区五区视频 | 国产麻豆一精品一av一免费| 亚洲一级网站| 欧美视频在线观看免费网址| 亚洲女爱视频在线| 在线观看亚洲专区| 1024欧美极品| 日韩视频一区二区在线观看 | 亚洲一区在线视频| 久久久久欧美| 久久久噜噜噜久久久| 国产亚洲一区二区精品| 91久久国产自产拍夜夜嗨| 精品99一区二区| 久久成人羞羞网站| 亚洲精品久久久久中文字幕欢迎你 | 国产美女一区二区| 日韩一二三在线视频播| 亚洲欧美日韩中文在线制服| 欧美精品三级在线观看| 亚洲成人自拍视频| 亚洲专区欧美专区| 欧美日精品一区视频| 久久国产主播| 亚洲激情中文1区| 欧美成人国产| 欧美伊人久久| 久久蜜桃资源一区二区老牛| 国产情侣一区| 欧美韩日精品| 亚洲精选国产| 久久se精品一区二区| 在线成人免费视频| 亚洲激情欧美| 欧美一级日韩一级| 国产亚洲成av人在线观看导航 | 一区二区三区毛片| 你懂的一区二区| 亚洲欧美综合网| 中文国产成人精品久久一| 亚洲乱码视频| 亚洲激情视频网站| 日韩午夜激情电影| 久久夜色精品国产亚洲aⅴ| 亚洲一二三四区| 亚洲日本在线观看| 国产精品欧美激情| 欧美在线地址| 一本色道久久88综合日韩精品| 亚洲国产欧美在线人成|