算法: skiplist 跳跃表代码实现和原理
SkipList在leveldb以及lucence中都广为使用,是比较高效的数据结构。由于它的代码以及原理实现的简单性,更为人们所接受。
所有操作均从上向下逐层查找,越上层一次next操作跨度越大。其实现是典型的空间换时间。
Skip lists are data structures that use probabilistic balancing rather than strictly enforced balancing.
As a result, the algorithms for insertion and deletion in skip lists are much simpler and significantly
faster than equivalent algorithms for balanced trees.
后面的图片来自:http://www.cnblogs.com/xuqiang/archive/2011/05/22/2053516.html
后面的代码当然是我自己写的呀。
(1)SkipList图示
(2)SkipList插入
(3)SkipList删除
(3)SkipList查找
查找操作也是上面的套路
实现中主要有几点需要注意:
(1) 如何支持各种数据类型的数据。 通用的做法就是 char数组保存value + char数组对应value的长度。
(2) 看图中,每个节点有多个指向不同层级的指针。代码中可以使用指针数组 + 节点的level来保存。
(3) 查找、插入、删除操作,都要找到(或者经过)需要操作点的前驱节点。这个操作可以封装起来,极大减少代码量。
(4) skiplist整体是一个链表, 设置一个头节点方便后续的各种操作。
数据结构如下:
truct SkipNode{
int key; //key
char *value; //value,可以支持任意类型
int length; //value_length, 记录数据长度
int level; //保存当前节点的level
SkipNode** next; //记录各层后续的地址
};
skiplist.h
class SkipList{
public:
SkipList(int level = );
~SkipList(); //根据key获取数据
int get(const int key, char* value, int &length); //链表插入新节点
int insert(
const int key,
const char* value,
const int length); //删除key对应节点
int del(const int key); private:
//初始化链表头, 路过链表
int init(); //空间释放
int deinit(); //新建一个节点
SkipNode* createNode(
const int key,
const char* value,
const int &length,
const int level); //所用随机函数获取一个level值, 用于后续新建节点使用
int getNewNodeLevel(); //init update node
int init_updatenode(); //get node pre(get update)
int get_update(const int key); //记录skiplist支持的最大level, 以及当前高度
int max_level;
int curr_level; SkipNode* List; //skiplist 第一个节点
SkipNode** Update; //记录每层搜索节点的前驱节点
};
cpp代码比较长,这里就不贴了。
算法: skiplist 跳跃表代码实现和原理的更多相关文章
- 小白也能看懂的Redis教学基础篇——朋友面试被Skiplist跳跃表拦住了
各位看官大大们,双节快乐 !!! 这是本系列博客的第二篇,主要讲的是Redis基础数据结构中ZSet(有序集合)底层实现之一的Skiplist跳跃表. 不知道那些是Redis基础数据结构的看官们,可以 ...
- 跳跃表Skip List的原理和实现
>>二分查找和AVL树查找 二分查找要求元素可以随机访问,所以决定了需要把元素存储在连续内存.这样查找确实很快,但是插入和删除元素的时候,为了保证元素的有序性,就需要大量的移动元素了.如果 ...
- 跳跃表Skip List的原理
1.二分查找和AVL树查找 二分查找要求元素可以随机访问,所以决定了需要把元素存储在连续内存.这样查找确实很快,但是插入和删除元素的时候,为了保证元素的有序性,就需要大量的移动元素了.如果需要的是一个 ...
- redis skiplist (跳跃表)
redis skiplist (跳跃表) 概述 redis skiplist 是有序的, 按照分值大小排序 节点中存储多个指向其他节点的指针 结构 zskiplist 结构 // 跳跃表 typede ...
- 浅析SkipList跳跃表原理及代码实现
本文将总结一种数据结构:跳跃表.前半部分跳跃表性质和操作的介绍直接摘自<让算法的效率跳起来--浅谈“跳跃表”的相关操作及其应用>上海市华东师范大学第二附属中学 魏冉.之后将附上跳跃表的源代 ...
- 【转】浅析SkipList跳跃表原理及代码实现
SkipList在Leveldb以及lucence中都广为使用,是比较高效的数据结构.由于它的代码以及原理实现的简单性,更为人们所接受.首先看看SkipList的定义,为什么叫跳跃表? "S ...
- 数据结构与算法(c++)——跳跃表(skip list)
今天要介绍一个这样的数据结构: 单向链接 有序保存 支持添加.删除和检索操作 链表的元素查询接近线性时间 ——跳跃表 Skip List 一.普通链表 对于普通链接来说,越靠前的节点检索的时间花费越低 ...
- SkipList 跳跃表
引子 考虑一个有序表:14->->34->->50->->66->72 从该有序表中搜索元素 < 23, 43, 59 > ,需要比较的次数分别为 ...
- 【Redis】skiplist跳跃表
有序集合Sorted Set zadd zadd用于向集合中添加元素并且可以设置分值,比如添加三门编程语言,分值分别为1.2.3: 127.0.0.1:6379> zadd language 1 ...
随机推荐
- 深入分析Spring Boot2,解决 java.lang.ArrayStoreException异常
将某个项目从Spring Boot1升级Spring Boot2之后出现如下报错,查了很多不同的解决方法都没有解决: Spring boot2项目启动时遇到了异常: java.lang.ArraySt ...
- ThreadLocal和InheritableThreadLocal使用
InheritableThreadLocal代码 public class InheritableThreadLocal<T> extends ThreadLocal<T> { ...
- HashMap分析 + 哈希表
http://www.cnblogs.com/hzmark/archive/2012/12/24/HashMap.html http://www.cnblogs.com/xqzt/archive/20 ...
- Django 性能测试
唐纳德·克努特(Donald Knuth)曾经说过:“不成熟的优化方案是万恶之源.”然而,任何一个承受高负载的成熟项目都不可避免地需要进行优化.在本文中,我想谈谈优化Web项目代码的五种常用方法.虽然 ...
- Go面试题精编100题
Golang精编100题 选择题 1. [初级]下面属于关键字的是()A. funcB. defC. structD. class 参考答案:AC 2. [初级]定义一个包内全局字符串变量,下 ...
- BZOJ.4695.最假女选手(线段树 Segment tree Beats!)
题目链接 区间取\(\max,\ \min\)并维护区间和是普通线段树无法处理的. 对于操作二,维护区间最小值\(mn\).最小值个数\(t\).严格次小值\(se\). 当\(mn\geq x\)时 ...
- iOS键盘类型最全
一.键盘风格 UIKit框架支持8种风格键盘. typedef enum { UIKeyboardTypeDefault, // 默认键盘:支持所有字符 UIKeyboa ...
- Asp.net core中的依赖注入
使用服务 在Asp.net core的Controller中,可以通过如下两种方式获取系统注入的服务: 构造函数 可以直接在构造函数中传入所依赖的服务,这是非常常见的DI注入方式. public Va ...
- STM32F4 SPI with DMA
STM32F4 SPI with DMA A few people have requested code, so I thought I’d post the code showing how I’ ...
- 使用Gitblit 搭建Windows Git服务器
使用Gitblit 搭建Windows Git服务器 整理使用Gitblit搭建Git服务器的步骤. 目录 使用Gitblit 搭建Windows Git服务器 目录 下载安装 配置 运行 客户端运行 ...