字典有一些形如
字典的節點
// 鍊錶節點定義
template
struct pairnode
pairnode(const pair& element) : element(element)
pairnode(const pair& element, pairnode* next)
: element(element)
};
字典類
這裡主要實現上述的操作
template
class sortedchain
int size() const
pair* find(const k&) const; // 查詢操作, 如果找到返回指標,否則返回null
void erase(const k&);
void insert(const pair&);
void output(ostream& out) const;
private:
pairnode* firstnode;
int dsize;
};
字典類的實現
find()
只需要一次遍歷,判斷currentnode->element.first
和thekey
是否相等
insert()
插入的時候首先通過查詢操作來確定字典中是否存在相同關鍵字的數對,如果有,則更新(因為是一對一的字典)
template
void sortedchain::insert(const pair& thepair)
// 如果存在相同的key值,更新
if(p != null && p->element.first == thepair.first)
// 插入
pairnode* newnode = new pairnode(thepair, p);
if(tmp == null)
firstnode = newnode;
else
tmp->next = newnode;
dsize++;
}
erase()template
void sortedchain::erase(const k& thekey)
if(p != null && p->element.first == thekey)
}
當我們在進行鍊錶查詢,刪除,新增的時候,要進行n次的比較,如果鍊錶的中間有乙個指標,那麼我們的這些操作次數可以減少一半。
增加額外的向前指標的鍊錶叫做跳表,因此它會比普通的鍊錶複雜一點。跳表結構的頭結點需要足夠的指標域,以滿足最大鍊錶級數的構建需要,而尾節點不需要指標域。
如下圖的結構我們叫做跳表,在該結構中有一組等級鍊錶,0級鍊錶包括所有數對,1級鍊錶每2個節點取乙個,2級鍊錶每4個取乙個,當然隔幾個取乙個指標不是固定的。
節點與字典節點結構有點不同,next指標變為指標陣列,即指標域
template
struct skipnode
};
跳表類
template
class skiplist
;
刪除
在刪除節點後需要重新更新級數
查詢例如,如果我們要查詢關鍵字為30的節點,find從最高端鍊錶開始查詢,知道0級鍊錶。在每一級鍊錶中採用逼近的方法,直到0級鍊錶,**如下:
部分**
template
pair* skiplist::find(const k& thekey) const
完整**/* 跳表實現 */
#ifndef _skiplist_h_
#define _skiplist_h_
#include
#include // rand_max
#include // ceil()
#include
using
namespace
std;
template
struct skipnode
skipnode(const pairtype& thepair, int size) : element(thepair)
};template
class skiplist
skiplist(k largekey, int maxpairs, float prob);
~skiplist();
// find, 如果找到返回指標,沒有返回null
pair* find(const k& thekey) const;
// level,級的分配
int level() const;
// search,搜尋
skipnode* search(const k& thekey) const;
// insert, 插入操作
void insert(const pair& thepair);
// erase,刪除操作
void erase(const k& thekey);
private:
float cutoff; // 用來確定層數
int levels; // 當前最大的非空鏈對
int dsize; // 字典的數對個數
int maxlevel; // 允許的最大鏈表層數
k tailkey; // 最大關鍵字
skipnode* headernode; // 頭結點指標
skipnode* tailnode; // 尾節點指標
skipnode** last; // last[i] 表示i層的最後節點
};template
skiplist::skiplist(k largekey, int maxpairs, float prob)
template
skiplist::~skiplist()
template
pair* skiplist::find(const k& thekey) const
template
int skiplist::level() const
template
skipnode* skiplist::search(const k& thekey) const
return beforenode->next[0];
}template
void skiplist::insert(const pair& thepair)
// 檢視關鍵字是否已經存在
skipnode* thenode = search(thepair.first);
if(thenode->element.first == thepair.first)
// 若不存在, 確定所在鏈級數
int thelevel = level();
if(thelevel > levels)
// 再借點thenode 之後插入新節點
skipnode* newnode = new skipnode(thepair, thelevel + 1);
for(int i = 0; i < thelevel; i++)
dsize++;
return;
}template
void skiplist::erase(const k& thekey)
#endif // !_skiplist_h_
資料結構之雜湊表之跳表
跳表結構如下 那麼我們來寫它需要的結構體以及所需函式 先是資料型別的結構體 struct datatype 這裡跟陣列雜湊是一樣的,乙個是需要取餘的鍵值,乙個是存放的資料 既然是鍊錶結構,那麼該有的鍊錶節點我們得寫一下,這個看我的資料結構專欄的帥哥都很熟悉,或者經常寫鍊錶的靚仔都很熟悉,所以直接上了...
redis 資料結構 跳表
要先有跳表的資料結構基礎 跳表是鍊錶的乙個變種,通過增加多餘的指標,將單向鍊錶變成多向鍊錶,進而使跳表的查詢效率和平衡二叉樹看齊 平均o logn 最壞o n 而且較之二叉樹實現方便。而跳表本身,有一些比較迷的實現策略 比如,新增節點的層次是通過隨機數 拋硬幣 指定的,存在乙個隨機概率,這在redi...
資料結構 跳表改造
儲存鍵值對id value值 儲存100萬資料對 查詢value區間,比如10到100 個數?查詢id區間,比如10到100 個數?查詢某id或某value,排名第幾?在跳表實體加個索引號 skiplist skiplist new skiplist skiplist.put 5,5 skiplis...