国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 編程 > C++ > 正文

C++實現位圖排序實例

2020-01-26 15:24:43
字體:
來源:轉載
供稿:網友

在《編程珠璣》一書里提到了一種算法導論里沒有提到過的位圖排序方法,這種排序方法是通過犧牲空間效率來追求時間效率(線性時間)以達到時間-空間折中與雙贏的目的。本文以實例形式簡單講一下位圖排序思想。

一、問題描述

     1.輸入:一個至多包含1千萬個非負整數的文件

     2.特征:①每個數都是小于10000000的非負整數;②沒有重復的數字;③數據之間不存在關聯關系。

     3.約束:①最多1MB的內存空間可用;②磁盤空間充足;③運行時間最多幾分鐘,最好是線性時間。
    
     4.輸出:按升序排列的整數序列。

二、位圖排序思想

由于待排序的數據記錄較多,我們單純地使用常見的排序方法時間效率較低,運行時間會很長。而且內存空間有限(限制為1MB左右),所以我們不能同時把所有整數讀入內存(如果每個整數使用7個字節來存儲,那么1MB內存空間只能存大約143000個數字)。當然我們可以多次讀取輸入文件,多次排序,但是更好的方案是使用位圖排序,可以使用有限的1MB內存空間并只進行一趟排序。

1.根據待排序集合中最大的數,開辟一個位數組,用來表示待排序集合中的整數;

2.待排序集合中的數字在位數組中的對應位置置1,其他的置0;

例如,待排序集合{1,2,3,5,8,13}可以表示為:0-1-1-1-0-1-0-0-1-0-0-0-0-1

這樣排序過程自然可以分為三步:

第一步:將所有的位都置為0;

第二步:通過讀入文件中的每個整數,將每個對應的位都置為1;

第三步:檢驗每一位,如果該位為1,輸出對應的整數。

注意:位圖排序是使用一個二進制位而不是一個整數來表示0或1,這樣可以大大地減少所需要的內存空間。使用位圖排序的前提是要知道待排序序列中的最大數。位圖排序的缺點是有些數沒有出現過,仍要為其保留一個位。故位圖排序比較適合關鍵字密集的序列,例如一個城市的電話號碼。

偽代碼如下:

/*Phase 1: initialize set to empty*/   for i = [0, n)     bit[i] = 0 /*Phase 2: insert present elements into the set*/   for each i in the input file     bit[i] = 1 /*Phase 3: write sorted output*/   for i = [0, n)     if bit[i] == 1       write i on the output file 

性能:時間復雜度可達O(n),1MB包含8*1024*1024個位,所需內存10000000/(8*1024*1024)=1.20MB,如果不是嚴格限制的話可以看做基本符合要求。

三、位圖排序實現

位圖排序時,我們需要考慮:給出一個數,如何找到其對應位圖的位置,方法就是首先找到該數對應的字節,然后在找到該數對應的位。例如:

unsigned char bitmap[2]; /* 可以表示16個數,即0~15 */ 

一個字節有八位,5表示第0個字節的第5位上;14表示第1個字節的第6個位上。

在這里為了簡化位處理,我們使用C++標準庫的bitset容器。bitset是C++提供的一種位集合的數據結構,它讓我們可以像使用數組一樣使用位,可以訪問指定下標的bit位。和其他容器一樣,bitset也是一個模板類。具體的bitset方法可以查看std::bitset reference。

下面我們使用bitset容器進行位圖排序:

/*************************************************************************   > File Name: BitSort.cpp   > Author: SongLee  ************************************************************************/ #include<bitset> #include<iostream> using namespace std;  #define MAX 20  int main() {   int arr[10] = {5,1,2,13,7,10,0,20,16,9};    bitset<MAX+1> bit;      /* 將對應位置置1 */   for(int i=0; i<10; ++i)   {     bit.set(arr[i]);     /* bit.set(n)表示將第n位置1 */   }    /* 輸出排序結果 */   for(int i=0; i<MAX+1; ++i)   {     /* bit.test(n)判斷第n位是否為1 */     if(bit.test(i))     {       cout << i << " ";     }   }   cout << endl; } 

輸出結果:0 1 2 5 7 9 10 13 16 20

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 宣城市| 宝坻区| 五河县| 凭祥市| 进贤县| 闽清县| 横山县| 义乌市| 肃南| 满洲里市| 防城港市| 黄石市| 灌阳县| 措美县| 九寨沟县| 隆安县| 南雄市| 布拖县| 呼和浩特市| 襄城县| 石林| 东至县| 寿宁县| 叶城县| 汝阳县| 商南县| 城步| 张家港市| 犍为县| 云林县| 乌鲁木齐市| 垦利县| 治县。| 会同县| 慈溪市| 龙里县| 鱼台县| 商洛市| 沙雅县| 成安县| 新河县|