對於排序問題,想必大家都非常熟悉。而且,應該都知道基於比較的排序方法的時間複雜度的下界是 o(n*logn)。儘管又出現了基數排序,使得排序類演算法的時間複雜度改進到 o(d*n),但是基數排序方法實現起來還是比較麻煩的。下面這種排序方法的時間複雜度可以認為是 o(n),但是和基數排序方法相比,它的實現非常簡單。
為了介紹這種方法,需要對輸入資料作如下假定:(1)都是非負整數,(2)每個整數最多出現一次,(3)最大整數小於 n。
這種方法採用雜湊函式的思想,用乙個整型陣列 array[n] 來實現對輸入資料的排序工作。具體點就是:(1)初始化,將陣列的每個元素清 0;(2)插入資料並實現排序,對於輸入資料 i,置 array[i] 為 1; (3)輸出排序結果,如果 array[i] 為 1,就輸出整數 i。
這種方法的優點是,可以邊輸入資料邊進行排序,這對於實時處理來說是非常合適的。當然它的缺點也是明顯的,不能處理負數和小數,當輸入資料的範圍很大時,陣列 array 會很大,要佔據非常大的記憶體空間,這樣對它的初始化就是一件比較費時的操作。
可能有人已經想到用 short int 型別陣列,或者 bool 型別陣列來實現演算法,以達到減少所需記憶體空間的目的。這些想法的關鍵就是用較少的記憶體,或者說二進位制位來標識每個資料。那麼在計算機中標識每個資料最少需要多少位呢?1 位!
在實現這種方法之前,先看一下它的記憶體需求和以前相比由多少改進。如果我們用整型陣列來實現排序,那麼標識乙個資料需要 32 位;如果用 bool 型別陣列來實現,需要 8 位;最後,如果用下面要說的位向量來實現的話,標識乙個資料只需 1 位。
所謂位向量就是由若干二進位制位組成的乙個向量。
例如 集合用位向量來表示 就是 :0 1 1 10100100001000000 代表集合中的數值位都置1,其他所有的位都置為0 。 計數是 0-19 可以表示所有小於20 的非負整數集合。
而我們熟知的 c++/c 中沒有對應乙個二進位制位的資料型別,因此,要實現位向量,需要借助於位操作。
下面是我實現的**:
#ifndef _intsetbitvec_
#define _intsetbitvec_
class intsetbitvec
n = 0;
}~intsetbitvec()
int size() // 返回實際輸入資料的個數
void insert(int t) // 插入資料,實現排序功能
void report(int *v) // 將排序後的資料儲存到指標 v 所指的整型陣列中
}private:
enum
; // mask = 0x3f
void set(int i) // 將位向量的第 i 位置 1
void clr(int i) // 將位向量的第 i 位清 0
int test(int i) // 檢測位向量第 i 位是否為 1
int n, hi, *x;
};#endif
位向量和排序
對於排序問題,想必大家都非常熟悉。而且,應該都知道基於比較的排序方法的時間複雜度的下界是 o n logn 儘管又出現了基數排序,使得排序類演算法的時間複雜度改進到 o d n 但是基數排序方法實現起來還是比較麻煩的。下面這種排序方法的時間複雜度可以認為是 o n 但是和基數排序方法相比,它的實現非...
位運算和排序
原碼 反碼 補碼 原碼 符號位加上真值的絕對值,用第一位表示符號,0為正,1為負,其餘位表示值。正數的原碼 反碼 補碼都相同。負數的反碼 原碼的符號位不變其餘位取反,補碼 反碼加1。位運算子 按位與 都為1時為1,有乙個0就為0 按位或,有1為1,全0為0 按位非,按位取反 按位異或,相同為0,不同...
實現位向量 1 6 2
如何使用位邏輯 例如與 或 移位 來實現位向量?解答 如下所示。如何使用位邏輯運算 例如與 或 移位 來實現位向量 from programming pearls by jon bentley bitsort.c bitmap sort from column 1 sort distinct int...