skiplist是鍊錶的變形,它在鍊錶的基礎上給每個元素增加了乙個高度,且每個元素的高度是乙個隨機值,因此skiplist是一種隨機化的資料結構。skiplist增、刪查、改的效率都非常高,是一種典型的以空間換時間的儲存方式。
常規的鍊錶如下:
而相同元素對應的skiplist結構如下:
由上可知,當要在鍊錶中查詢某個元素時,必須從煉表頭乙個乙個遍歷,而在skiplist中查詢某個元素時,查詢卻是跳躍的,因此將其稱為skiplist。
如要查詢元素25時,對於單鏈表,要遍歷到第9個節點才能找到。而對於skiplist,只需要經過2次比較即可(表頭到元素6再到25),效率非常高。
當查詢的效率高了之後,插入、刪除、修改的效率自然也就變高了
skiplist中的每個節點,都包含有乙個值和乙個陣列,其中陣列元素的個數即為當前節點的高度,陣列中對應位置的元素儲存的是指向同一高度的下一節點的指標(如next[0]指向level 0的下一節點,next[3]指向level 3的下一節點),因此陣列可用乙個二級指標表示。
template
struct skiplistnode;
skiplist類中的成員變數只包含了當前鍊錶的最大高度和表頭
template
class skiplist
~skiplist();
bool insert(const
std::pair& value);
node* find(keytype& key) const;
bool remove(keytype& key);
int getlevel() const
private:
node* createnode(std::pairkey,int level);
void destroynode(node *node);
int level_;//skiplist中節點的最大高度
node *head_;//表頭元素
};
skiplist在建構函式中呼叫createnode()得到表頭節點,表頭首先會初始化系統規定的最大高度個陣列元素,假設最大高度為4
node* createnode(std::pairvalue,int level)
經過建構函式構造的表頭如下:
鍊錶的增、刪、查、改中,查詢操作是最核心的,其他操作均是建立在查詢的基礎上的
1)查詢元素
node* find(keytype key) const
node=node->next[0];
if(node==null||node->keyvalue.first!=key) return
null;
else
return node;
}
2)插入元素
bool insert(const std::pair& value)
node=node->next[0];
if(node!=null&&node->keyvalue.first==value.first) return
false;//若已存在於要插入元素的key值相等的,則不插入直接返回
int newlevel=getrandomlevel();//隨機產生要插入元素的高度
if(level_//當新的高度大於原來鍊錶中的最大高度時,說明此時從level_到newlevel高度均為空,還沒有初始值
for(int i=level_;i//則說明新節點從level_到newlevel的直接前驅都只會是head_,將其存放在update中
level_=newlevel;//更新此時鍊錶的最大高度
}node=createnode(value,newlevel);//建立新節點
for(int i=0;i//然後將新節點插入到skiplist中,基本操作與鍊錶相似,只不過節點的不同高度的直接前驅都不同
node->next[i]=update[i]->next[i];
update[i]->next[i]=node;
}return
true;
}
以要插入元素17為例(假設其他元素都已經存在),此時的level_=4
for(int i=level_-1;i>=0;--i)
得到後面要更新的節點update: update[3]=6,update[2]=6,update[1]=9,update[0]=12
同時newlevel=2
for(int i=0;i//與一般節點的插入類似,要對每一高度的節點更新插入
node->next[i]=update[i]->next[i];
update[i]->next[i]=node;
}
這樣就將元素插入到skiplist中 LevelDB之整體結構
資料庫和儲存引擎。資料庫往往是乙個比較豐富完整的系統,提供了sql查詢語言,事務和水平擴充套件等支援。然而儲存引擎則是小而精,純粹專注於單機的讀 寫 儲存。一般來說,資料庫底層往往會使用某種儲存引擎。目前開源的kv儲存引擎中,rocksdb是流行的乙個,mongodb和mysql底層可以切換成roc...
深入leveldb 初步認識leveldb
1.leveldb簡介 leveldb是google兩位工程師實現的單機版k v儲存系統,具有以下幾個特點 1.key和value都是任意的位元組陣列,支援記憶體和持久化儲存 2.資料都是按照key排序 3.使用者可以重寫排序函式 4.包含基本的資料操作介面,put key,value get ke...
LevelDB原始碼剖析之Memtable 1
memtable是leveldb很重要的一塊,leveldb的核心之一。我們肯定關注kv資料在memtable中是如何組織的,秘密在skip list中。在leveldb中,所有記憶體中的kv資料都儲存在memtable中,物理disk則儲存在sstable中。在系統執行過程中,如果memtable...