撸过一遍代码之后,对一些数据结构才能更深的了解
读完redis的跳跃表,现在用c++重新实现了插入、查询和删除3个api方法,
理解下来跳跃表,
主要思路有
1. 从上层逐渐到下层搜索,上层步长更大,这样上层迅速定位到一个更接近的点。
2. 下层用于精细化查找,速度更慢
3. 与有序数组相似,有序数组的查找效率是N,这个为logN
主要用途:
1. 网络框架中,根据sequence id查找回包。
2. 字符串匹配
#include "zskiplist.h"
#include <iostream>
namespace common{
template<typename T>
CSkipListNode<T>::CSkipListNode(uint32_t level , T value){
for(int i = 0 ; i < level ; i++){
_Level[i].span = 0 ;
_Level[i].forward = NULL;
}
this->_Value = value ;
this->_BackwardNode = NULL;
}
template<typename T>
CSkipList<T>::CSkipList(){
_Level = 1 ;
_Length = 0 ;
_Head = new CSkipListNode<T>(SKIPLIST_MAX_LEVEL, 0 );
_Tail = NULL;
srand((int)time(0));
}
template<typename T>
bool CSkipList<T>::Insert(T value){
uint32_t rank[SKIPLIST_MAX_LEVEL];
CSkipListNode<T> *update[SKIPLIST_MAX_LEVEL];
CSkipListNode<T> *node = this->_Head;
for(int i = this->_Level - 1; i >= 0 ; i--){
rank[i] = i == (this-> _Level - 1) ? 0 : rank[i+1];
while(node->GetLevel(i)->forward != NULL &&
node->GetLevel(i)->forward->GetNodeValue() < value){
rank[i] += node->GetLevel(i)->span;
node = node->GetLevel(i)->forward;
}
update[i] = node;
}
int level = GetRandomLevel() + 1;
if(level > _Level){
for(int i = _Level ; i < level ; i++){
rank[i] = 0 ;
update[i] = _Head;
update[i]->GetLevel(i)->span = _Length;
}
_Level = level;
}
CSkipListNode<T> *new_node = new CSkipListNode<T>(level, value );
for(int i = 0 ; i < level ; i++){
new_node->GetLevel(i)->forward = update[i]->GetLevel(i)->forward;
update[i]->GetLevel(i)->forward = new_node ;
new_node->GetLevel(i)->span = update[i]->GetLevel(i)->span - (rank[0] - rank[i]) ;
update[i]->GetLevel(i)->span = (rank[0] - rank[i]) + 1;
}
for(int i = level ; i < _Level ; i++){
update[i]->GetLevel(i)->span++ ;
}
if(update[0] == _Head) {
new_node->SetBackWard(NULL);
}else{
new_node->SetBackWard(update[0]);
}
if(new_node->GetLevel(0)->forward){
new_node->GetLevel(0)->forward->SetBackWard(new_node);
}else{
_Tail = new_node;
}
_Length++;
return true;
}
template<typename T>
uint32_t CSkipList<T>::GetRank(T value){
CSkipListNode<T> *node = this->_Head;
uint32_t rank = 0 ;
for(int i = this->_Level - 1; i >= 0 ; i--){
while(node->GetLevel(i)->forward &&
node->GetLevel(i)->forward->GetNodeValue() < value){
rank += node->GetLevel(i)->span;
node = node->GetLevel(i)->forward;
}
}
// std::cout <<std::endl <<node->GetNodeValue() << " " <<node->GetLevel(0)->forward->GetNodeValue() << " " << value ;
if( node->GetLevel(0)->forward && node->GetLevel(0)->forward->GetNodeValue() == value) {
return rank + node->GetLevel(0)->span;
}
return 0;
}
template<typename T>
bool CSkipList<T>::Delete(T value){
CSkipListNode<T> *node = this->_Head;
CSkipListNode<T> *update[SKIPLIST_MAX_LEVEL];
uint32_t rank = 0 ;
for(int i = this->_Level - 1; i >= 0 ; i--){
while(node->GetLevel(i)->forward &&
node->GetLevel(i)->forward->GetNodeValue() < value){
node = node->GetLevel(i)->forward;
}
update[i] = node;
}
while(node->GetLevel(0)->forward &&
node->GetLevel(0)->forward->GetNodeValue() == value){
node = node->GetLevel(0)->forward ;
DeleteNode(node, update);
delete node;
}
return true;
}
template<typename T>
bool CSkipList<T>::DeleteNode(CSkipListNode<T> *node, CSkipListNode<T> **update){
for (int i = 0; i < _Level; i++) {
if (update[i]->GetLevel(i)->forward == node) {
update[i]->GetLevel(i)->span += node->GetLevel(i)->span - 1;
update[i]->GetLevel(i)->forward = node->GetLevel(i)->forward;
} else {
update[i]->GetLevel(i)->span -= 1;
}
}
if (node->GetLevel(0)->forward) {
node->GetLevel(0)->forward->SetBackWard(node->GetBackWard());
} else {
_Tail = node->GetBackWard();
}
while(_Level > 1 && _Head->GetLevel(_Level-1)->forward == NULL)
_Level--;
--_Length;
return true;
}
};
#include <stdint.h>
#include <stdlib.h>
#include <time.h>
#define SKIPLIST_MAX_LEVEL 32
namespace common{
template <typename T>
class CSkipListNode{
public:
typedef struct SkipListLevel{
uint32_t span;
CSkipListNode *forward;
}SkipListLevel;
CSkipListNode(uint32_t level , T value);
SkipListLevel *GetLevel(uint32_t level){return &_Level[level];};
T GetNodeValue(){return _Value;};
CSkipListNode *SetBackWard(CSkipListNode * node) {_BackwardNode = node;}
CSkipListNode *GetBackWard() {return _BackwardNode;}
private:
SkipListLevel _Level[SKIPLIST_MAX_LEVEL];
CSkipListNode *_BackwardNode;
T _Value;
};
template <typename T>
class CSkipList{
public :
CSkipList();
bool Insert(T value);
bool Delete(T value);
uint32_t GetRank(T value);
uint32_t GetRandomLevel(){
return rand() % SKIPLIST_MAX_LEVEL ;
};
private:
CSkipListNode<T> *_Head ;
CSkipListNode<T> *_Tail ;
uint32_t _Level;
uint32_t _Length;
private:
bool DeleteNode(CSkipListNode<T> *node, CSkipListNode<T> **update);
};