在所有具有效能優化的資料結構中,我想大家使用最多的就是hash表,是的,在具有定位查詢上具有o(1)的常量時間,多麼的簡潔優美,
但是在特定的場合下:
①:對10億個不重複的整數進行排序。
②:找出10億個數字中重複的數字。
當然我只有普通的伺服器,就算2g的記憶體吧,在這種場景下,我們該如何更好的挑選資料結構和演算法呢?
一:問題分析
這年頭,大牛們寫的排序演算法也就那麼幾個,首先我們算下放在記憶體中要多少g: (10億 * 32)/(1024*1024*1024*8)=3.6g,可憐
的2g記憶體直接爆掉,所以各種神馬的資料結構都玩不起來了,當然使用外排序還是可以解決問題的,由於要走io所以暫時剔除,因為我們
要玩高效能,無望後我們想想可不可以在二進位制位上做些手腳?
比如我要對這四個byte型別的數字做排序,該怎麼做呢?我們知道byte是佔8個bit位,其實我們可以將陣列中的值作為bit位的
key,value用」0,1「來標識該key是否出現過?下面看圖:
從圖中我們精彩的看到,我們的陣列值都已經作為byte中的key了,最後我只要遍歷對應的bit位是否為1就可以了,那麼自然就成有序陣列了。
可能有人說,我增加乙個13怎麼辦?很簡單,乙個位元組可以存放8個數,那我只要兩個byte就可以解決問題了。
可以看出我將乙個線性的陣列變成了乙個bit位的二維矩陣,最終我們需要的空間僅僅是:3.6g/32=0.1g即可,要注意的是bitmap排序不
是n的,而是取決於待排序陣列中的最大值,在實際應用上關係也不大,比如我開10個執行緒去讀byte陣列,那麼複雜度為:o(max/10)。
二:**
我想bitmap的思想大家都清楚了,這一次又讓我們見證了二進位制的魅力,當然這些移位都是位運算的工作了,熟悉了你就玩轉了。
1:clear方法(將陣列的所有bit位置0)
比如要將當前4對應的bit位置0的話,只需要1左移4位取反與b[0] & 即可。
#region 初始化所用的bit位為0
/// /// 初始化所用的bit位為0
///
///
static void clear(byte i)
#endregion
2:add方法(將bit置1操作)
同樣也很簡單,要將當前4對應的bit位置1的話,只需要1左移4位與b[0] | 即可。
#region 設定相應bit位上為1
/// /// 設定相應bit位上為1
///
///
static void add(byte i)
#endregion
2:contain方法(判斷當前bit位是否是1)
如果看懂了clear和add,我相信最後乙個方法已經不成問題了。
#region 判斷當前的x在陣列的位中是否存在
/// ///判斷當前的x在陣列的位中是否存在
///
///
///
static bool contain(byte i)
#endregion
最後上總的**:
using system;
using system.collections.generic;
using system.linq;
using system.text;
using system.diagnostics;
using system.threading;
using system.io;
", s);
s = contain(5);
console.writeline("當前是否包含5:", s);
console.read();
}#region 初始化所用的bit位為0
/// /// 初始化所用的bit位為0
///
///
static void clear(byte i)
#endregion
#region 設定相應bit位上為1
/// /// 設定相應bit位上為1
///
///
static void add(byte i)
#endregion
#region 判斷當前的x在陣列的位中是否存在
/// ///判斷當前的x在陣列的位中是否存在
經典演算法題每日演練 第十一題 Bitmap演算法
在所有具有效能優化的資料結構中,我想大家使用最多的就是hash表,是的,在具有定位查詢上具有o 1 的常量時間,多麼的簡潔優美,但是在特定的場合下 對10億個不重複的整數進行排序。找出10億個數字中重複的數字。當然我只有普通的伺服器,就算2g的記憶體吧,在這種場景下,我們該如何更好的挑選資料結構和演...
經典演算法題每日演練 第十二題 線段樹
這一篇我們來看樹狀陣列的加強版線段樹,樹狀陣列能玩的線段樹一樣可以玩,而且能玩的更好,他們在區間求和,最大,平均 等經典的rmq問題上有著對數時間的優越表現。一 線段樹 線段樹又稱 區間樹 在每個節點上儲存乙個區間,當然區間的劃分採用折半的思想,葉子節點只儲存乙個值,也叫單元節點,所 以最終的構造就...
經典演算法題每日演練 第十九題 雙端佇列
話說大學的時候老師說妹子比工作重要 工作可以再換,妹子這個。所以。這兩個月也就一直忙著fall in love,嗨,慢慢調整心態吧,這篇就選乙個簡單的資料結構聊一聊,話說有很多資料結構都在玩組合拳,比如說 塊狀鍊錶,塊狀陣列,當然還有本篇的雙端佇列,是的,它就是 棧和佇列的組合體。一 概念 我們知道...