redis skiplist閱讀

擼過一遍代碼之後,對一些數據結構才能更深的瞭解

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

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章