資料結構之跳表

2021-07-23 18:26:46 字數 4087 閱讀 4700

字典有一些形如

字典的節點

// 鍊錶節點定義

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.firstthekey是否相等

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...