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

羅朝輝(飄飄白云)

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

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

排序算法之分配排序   

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

轉載請注明出處

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


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

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

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

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

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


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


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


桶排序和基數排序均屬于分配排序。分配排序的基本思想:排序過程無須比較關鍵字,而是通過用額外的空間來"分配"和"收集"來實現排序,它們的時間復雜度可達到線性階:O(n)。簡言之就是:用空間換時間,所以性能與基于比較的排序才有數量級的提高!


桶排序(Bucket Sort),也稱箱排序

基本思想:設置若干個箱子,依次掃描待排序的記錄 array[0],array[1],…,array[n - 1],把關鍵字等于 k 的記錄全都裝入到第 k 個箱子里(分配),然后按序號依次將各非空的箱子里的記錄收集起來,從而完成排序。


桶排序所需要的額外空間取決于關鍵字的個數,若 array[0..n - 1] 中關鍵字的取值范圍是 0 到 m - 1 的整數,則必須設置 m 個箱子。因此箱排序要求關鍵字的類型是有限類型,否則可能要無限個箱子。一般情況下每個箱子中存放多少個關鍵字相同的記錄是無法預料的,故箱子的類型應設計成鏈表為宜。


在實現上,桶排序一般采用另外的變種。即:把 [0, m) 劃分為 m 個大小相同的子區間,每一子區間是一個桶。然后將 n 個記錄分配到各個桶中。因為關鍵字序列是均勻分布在[0,m)上的,所以一般不會有很多個記錄落入同一個桶中。由于同一桶中的記錄其關鍵字不盡相同,所以必須采用關鍵字比較的排序方法(通常用插入排序)對各個桶進行排序,然后依次將各非空桶中的記錄收集起來即可。


C 代碼實現:

struct bucket_node {
    
int key;
    bucket_node
* next;
}
;

// 取得數組中最大數的位數
int get_max_digital_count(int* array, int length)
{
    assert(array 
&& length > 0);

    
int i = 0;
    
int max = array[0];
    
int maxDigitalCount = 1;

    
for (i = 1; i < length; i++{
        
if (max < array[i]) {
            max 
= array[i];
        }

    }


    
while ((max / 10> 0{
        max 
%= 10;
        
++maxDigitalCount;
    }


    
return maxDigitalCount;
}


// 取得數 num 中從低到高第 n 位上的數字
int get_ditital_at(int num, int n)
{
    
while (--> 0{
        num 
/= 10;
    }


    
return (num % 10);
}


// 箱/桶排序
//
void bucket_sort(int* array, int length)
{
    assert(array 
&& length >= 0);

    
if (length <= 1{
        
return;
    }


    
int i, index;
    bucket_node
* temp = NULL;
    bucket_node bucket[
10= {0, };    // 根據數字個數 0 ~ 9 建立 10 個桶

    
int count = get_max_digital_count(array, length);

    
// 建立數據節點
    bucket_node* data = (bucket_node*)malloc(length * sizeof(bucket_node));
    
if (!data) {
        printf(
"Error: out of memory!\n");
        
return;
    }


    
for (i = 0; i < length; i++{
        data[i].key 
= array[i];
        data[i].next 
= NULL;
    }


    
// 分配
    for (i = 0; i < length; i++{
        index 
= get_ditital_at(data[i].key, count);
        
if (bucket[index].next == NULL) {
            bucket[index].next 
= &data[i];
        }

        
else {
            temp 
= &bucket[index];
            
while (temp->next != NULL && temp->next->key < data[i].key) {
                temp 
= temp->next;
            }


            data[i].next 
= temp->next;
            temp
->next = &data[i];
        }

    }


    
// 收集
    index = 0;
    
for (i = 0; i < 10; i++{
        temp 
= bucket[i].next;
        
while (temp != NULL) {
            array[index
++= temp->key;
            temp 
= temp->next;
        }

    }



    free(data);
}


時間復雜度分析:
桶排序的平均時間復雜度是線性的,即 O(n)。但最壞情況仍有可能是 O(n ^ 2)。

空間復雜度分析:
桶排序只適用于關鍵字取值范圍較小的情況,否則所需箱子的數目 m 太多導致浪費存儲空間和計算時間。

基數排序(Radix Sort)
基本思想:基數排序是對桶排序的改進和推廣。如果說桶排序是一維的基于桶的排序,那么基數排序就是多維的基于桶的排序。我這么說,可能還不是太清楚。比方說:用桶排序對 [0, 30] 之間的數進行排序,那么需要 31 個桶,分配一次,收集一次,完成排序;那么基數排序則只需要 0 - 9 總共 10 個桶(即關鍵字為數字 0 - 9),依次進行個位和十位的分配和收集從而完成排序。

C 代碼實現:

// 基數排序
//
void radix_sort(int* array, int length)
{
    assert(array 
&& length >= 0);

    
if (length <= 1{
        
return;
    }


    
const int buffer_size = length * sizeof(int);

    
int i, k, count, index;
    
int bucket[10= {0, };    // 根據數字個數 0 ~ 9 建立 10 個桶

    
int* temp = (int*)malloc(buffer_size);
    
if (!temp) {
        printf(
"Error: out of memory!\n");
        
return;
    }


    count 
= get_max_digital_count(array, length);

    
for (k = 1; k <= count; ++k) {
        memset(bucket, 
010 * sizeof(int));

        
// 統計各桶中元素的個數
        for (i = 0; i < length; ++i) {
            index 
= get_ditital_at(array[i], k);
            
++bucket[index];
        }


        
// 為每個記錄創建索引下標
        for (i = 1; i < 10++i) {
            bucket[i] 
+= bucket[i - 1];
        }


        
// 按索引下標順序排列
        for (i = length - 1; i >= 0--i) {
            index 
= get_ditital_at(array[i], k);
            assert(bucket[index] 
- 1 >= 0);
            temp[
--bucket[index]] = array[i];
        }


        
// 一趟桶排序完畢,拷貝結果
        memcpy(array, temp, buffer_size);

#ifdef DEBUG_SORT
        debug_print(
" 第 %d 趟排序:", k);
        
for (i = 0; i < length; ++i) {
            debug_print(
"%d ", array[i]);
        }


        debug_print(
"\n");
#endif
    }


    free(temp);
}


時間復雜度分析:
基數排序的時間負責度為 O(n)。

空間復雜度:
基數排序所需的輔助存儲空間為 O(n + r * d),其中 r 為記錄中關鍵字分量的最大個數,d 為關鍵字的個數。比如說:待排序為 0 - 999,那么分量的最大個數為 3,關鍵字的個數為 10(0 - 9)。

補充:
基數排序是穩定的。

若排序文件不是以數組 array 形式給出,而是以單鏈表形式給出(此時稱為鏈式的基數排序),則可通過修改出隊和入隊函數使表示箱子的鏈隊列無須分配結點空間,而使用原鏈表的結點空間。人隊出隊操作亦無需移動記錄而僅需修改指針。雖然這樣一來節省了一定的時間和空間,但算法要復雜得多,且時空復雜度就其數量級而言并未得到改觀。

=======================================================================================
測試:
在前文《排序算法之插入排序》測試代碼的基礎上添加兩行代碼即可:
 {"桶/箱排序",    bucket_sort},
 {"基數排序",     radix_sort},

測試結果:

=== 桶/箱排序 ===
 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
 第 1 趟排序:10 91 32 72 42 65 27 8 18 58 49
 第 2 趟排序:8 10 18 27 32 42 49 58 65 72 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
 第 1 趟排序:10 0 1 2 3 4 5 6 7 8 9
 第 2 趟排序:0 1 2 3 4 5 6 7 8 9 10
   sorted: 0 1 2 3 4 5 6 7 8 9 10

posted on 2011-03-18 23:47 羅朝輝 閱讀(910) 評論(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>
            麻豆亚洲精品| 欧美国产日韩xxxxx| 国产日韩欧美三区| 中文国产成人精品久久一| 久久精品久久综合| 快射av在线播放一区| 久久美女性网| 牛人盗摄一区二区三区视频| 一区二区日韩伦理片| 国产麻豆精品视频| 国产日韩精品一区二区浪潮av| 国产字幕视频一区二区| 在线观看一区二区视频| 日韩午夜电影av| 欧美午夜欧美| 欧美日韩精品免费在线观看视频| 国产精品推荐精品| 亚洲国产精品久久久久秋霞影院| 亚洲天堂成人在线观看| 久久在线免费观看视频| 精品1区2区| 亚洲精品一线二线三线无人区| 中文网丁香综合网| 久久综合九色综合网站| 欧美日韩国产不卡| 亚洲国产成人porn| 国产一区二区你懂的| 国产亚洲欧洲| 一区二区三区**美女毛片| 亚洲国产成人高清精品| 亚洲欧美中文日韩在线| 国产精品一区二区在线观看网站 | 中文日韩欧美| 欧美激情中文字幕一区二区| 亚洲国产精品欧美一二99| 欧美中文在线观看| 亚洲欧美日韩一区二区在线| 久久国产精品99久久久久久老狼| 欧美激情第9页| 久久久久网址| 亚洲精品欧美激情| 亚洲国产毛片完整版| 欧美日韩免费观看一区二区三区 | 欧美一区综合| 国产欧美日韩视频一区二区三区| 国产一区在线观看视频| 亚洲无线视频| 日韩一级黄色片| 国产人成一区二区三区影院| 久久综合99re88久久爱| 欧美黄色aa电影| 黄色工厂这里只有精品| 欧美午夜精品理论片a级按摩| 一区二区三区免费观看| 欧美一区免费视频| 亚洲精品色图| 久久精品亚洲乱码伦伦中文 | 国产欧美日韩在线观看| 久久福利影视| 国产精品久久国产三级国电话系列| 久久综合给合| 国产精品第一区| 国产一区二区精品| 亚洲国产成人精品视频| 国产日韩在线一区| 亚洲欧洲一区| 亚洲伦理在线观看| 久久久亚洲国产美女国产盗摄| 欧美在线3区| 这里只有精品在线播放| 国产精品yjizz| 最近中文字幕mv在线一区二区三区四区| 国产欧美日韩视频在线观看| 亚洲精品欧美日韩| a4yy欧美一区二区三区| 男人天堂欧美日韩| 欧美一级专区| 免费观看成人| 欧美成人免费一级人片100| 国产欧美日本一区二区三区| 销魂美女一区二区三区视频在线| 亚洲免费伊人电影在线观看av| 欧美激情一区二区在线| 亚洲一区二区伦理| 国产精品久久一卡二卡| 亚洲欧美99| 午夜欧美大尺度福利影院在线看| 91久久精品国产91久久| 国产精品wwwwww| 亚洲人成艺术| 伊人久久亚洲热| 久久中文字幕一区二区三区| 欧美xart系列在线观看| 亚洲日韩欧美视频| 国产亚洲成av人在线观看导航| 久久国产福利| 欧美一区二区精品| 国产精品日韩在线一区| 久久国产高清| 亚洲欧美久久久久一区二区三区| 久久精品一级爱片| 一区二区三区高清不卡| 黑人巨大精品欧美黑白配亚洲| 亚洲毛片播放| 国产精品99久久久久久白浆小说 | 99re国产精品| 在线成人免费视频| 国产日韩欧美日韩| 国产日韩欧美在线| 欧美性色视频在线| 欧美国产第一页| 亚洲一区二区视频在线| 亚洲破处大片| 日韩亚洲视频| 亚洲精品国产拍免费91在线| 欧美国产日本在线| 欧美激情一区二区三区在线视频观看| 你懂的国产精品| 欧美在线视频二区| 亚洲欧美日本另类| 久久久久久网| 美日韩精品视频| 欧美日韩一区二区三区四区在线观看| 欧美日本国产在线| 欧美主播一区二区三区美女 久久精品人| 国内成+人亚洲+欧美+综合在线| 欧美成人一区二区三区| 欧美日韩精品免费观看视频完整| 欧美大尺度在线| 国产精品视频第一区| 亚洲精品三级| 亚洲作爱视频| 亚洲精品美女久久久久| 日韩视频免费在线观看| 午夜精品久久久久久99热| 久久夜色精品国产欧美乱| 亚洲国产欧美一区| 午夜一区二区三区在线观看| 亚洲美女中文字幕| 久久综合网络一区二区| 亚洲日本中文字幕| 久久久久久999| 国产精品久久福利| 亚洲婷婷在线| 亚洲精品一区二| 免费永久网站黄欧美| 香蕉久久夜色精品国产使用方法| 久久综合久久综合九色| 国产精品中文字幕欧美| 亚洲午夜激情| 亚洲欧洲三级电影| 欧美日韩精品是欧美日韩精品| 国语精品一区| 欧美激情精品久久久久久免费印度| 中国亚洲黄色| 亚洲激情女人| 欧美日一区二区在线观看 | 久久久精品999| 欧美在线播放视频| 国产精品久久久久久久久久久久久| 樱桃国产成人精品视频| 亚洲国产精品一区二区三区| 亚洲欧美www| 亚洲一区二区三区在线看| 国产欧美精品久久| 噜噜噜久久亚洲精品国产品小说| 亚洲国产欧美日韩| 欧美~级网站不卡| 亚洲视频在线二区| 久久成人18免费网站| 亚洲精品一品区二品区三品区| 99精品国产热久久91蜜凸| 国产免费成人在线视频| 美女国产一区| 欧美激情精品久久久久| 欧美成人福利视频| 久久久久免费| 国产精品久久九九| 一本色道88久久加勒比精品| 国产真实乱子伦精品视频| 一区二区三区四区五区视频 | 亚洲一区二区三区影院| 亚洲精品日韩综合观看成人91| 午夜精品久久久| 国产区亚洲区欧美区| 亚洲一区二区三区在线观看视频| 136国产福利精品导航| 久热国产精品| 男人的天堂亚洲在线| 在线色欧美三级视频| 久久精品麻豆| 久久爱另类一区二区小说| 国产精品日韩精品| 亚洲精品看片| 日韩视频国产视频| 欧美日韩视频不卡| 亚洲女人av| 另类酷文…触手系列精品集v1小说| 韩国v欧美v日本v亚洲v| 最新亚洲一区|