redis skiplist阅读

6 篇文章 0 订阅

撸过一遍代码之后,对一些数据结构才能更深的了解

读完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);
};

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值