閱讀841 返回首頁    go 阿裏雲 go 技術社區[雲棲]


位圖排序

《編程珠璣》第一章第一題就相當的精彩,做個筆記。題目如下:
輸入:   一個包含n個正整數的文件,每個正整數小於n,n等於10的7次方(一千萬)。並且文件內的正整數沒有重複和關聯數據。

輸出:  輸入整數的升序排列
 
約束: 限製在1M左右內存,充足的磁盤空間

    假設整數占32位,1M內存可以存儲大概250000個整數,第一個方法就是采用基於磁盤的合並排序算法,第二個辦法就是將0-9999999切割成40個區間,分40次掃描(10000000/250000),每次讀入250000個在一個區間的整數,並在內存中使用快速排序。書中提出的第三個解決辦法是采用bitmap(或者稱為bit vector)來表示所有數據集合(注意到條件,數據沒有重複),這樣就可以一次性將數據讀入內存,減少了掃描次數。算法的偽代碼如下:
階段1:初始化一個空集合
     for i=[0,n)
           bit[i]=0;
階段2:讀入數據i,並設置bit[i]=1
    for each i in the input file
           bit[i]=1;
階段3:輸出排序的結果
   for i=[0,n)
          if bit[i]==1
              write i on the output file

這個算法的時間複雜度在O(n),用c語言寫的版本可以在10秒內完成任務!c語言的源碼在該書主頁上有,這裏給一個java的測試版,加上我的理解注釋:

/**
 * Created by IntelliJ IDEA.
 * User: zhuangxd
 * Date: 2008-1-7
 * Time: 14:30:44
 
*/
public class BitSortTest {
    
private static final int BITSPERWORD = 32;  //整數位數
    private static final int SHIFT = 5;
    
private static final int MASK = 0x1F;  //5位遮蔽 0B11111
    private static final int N = 10000000;
    
//用int數組來模擬位數組,總計(1 + N / BITSPERWORD)*BITSPERWORD位,足以容納N
    private static int[] a = new int[(1 + N / BITSPERWORD)];

    
public static void main(String[] args) {
        bitsort(
new int[]{11002100009999456778902});
    }

    
public static void bitsort(int[] array) {
        
for (int i = 0; i < N; i++)
            clr(i);   
//位數組所有位清0
        for (int i = 0; i < array.length; i++)
            set(array[i]);  
//階段2
        for (int i = 0; i < N; i++)
            
if (test(i))
                System.out.println(i);
    }

    
//置a[i>>SHIFT]的第(i & MASK)位為1,也就是位數組的第i位為1
    public static void set(int i) {
        a[i 
>> SHIFT] |= (1 << (i & MASK));
    }

    
//置a[i>>SHIFT]的第(i & MASK)位為0,也就是位數組的第i位為0
    public static void clr(int i) {
        a[i 
>> SHIFT] &= ~(1 << (i & MASK));
    }

    
//測試位數組的第i位是否為1
    public static boolean test(int i) {
        
return (a[i >> SHIFT] & (1 << (i & MASK))) == (1 << (i & MASK));
    }
}
文章轉自莊周夢蝶  ,原文發布時間2008-01-07

最後更新:2017-05-17 17:02:00

  上一篇:go  江蘇金融網貸APP平台開發
  下一篇:go  介紹一個輕量級java的swf處理庫