• 对单链表查找一个元素的时间复杂度是 O(n)
  • 通过对链表建立多级索引的结构,就是跳表,查找任意数据、插入数据、删除数据的时间复杂度均为 O(log n)
  • 前提:建立了索引,用空间换时间的思路
  • (每两个节点建立一个索引)索引节点总和 n/2+n/4+n/8+…+8+4+2 = n-2,空间复杂度 O(n)
  • 插入和删除后,动态更新索引,避免局部链表元素过多或者过少,退化成单链表

    skiplist.h
/*** @description: 跳表* @author: michael ming* @date: 2019/4/22 22:21* @modified by: */#ifndef SKIPLIST_SKIPLIST_H
#define SKIPLIST_SKIPLIST_H
#include <ctime>
#include <cstdlib>
#include <iostream>
using namespace std;
typedef unsigned int UINT;
template <class T>
class skipNode
{public:T data;skipNode<T> **next; //跳表节点的next是 skipNode<T>* 类型的数组skipNode(const UINT level){next = new skipNode<T>* [level+1];  //索引级别从0(链表自身)开始for(int i = 0; i < level+1; ++i)next[i] = NULL;}skipNode(const UINT level, const T& inputdata):data(inputdata){next = new skipNode<T>* [level+1];  //索引级别从0(链表自身)开始for(int i = 0; i < level+1; ++i)next[i] = NULL;}~skipNode<T>(){delete [] next;}
};
template <class T>
class skiplist
{private:UINT randomLevel(){//        static bool flag = false;
//        if(!flag)
//        {//            srand(UINT(time(0)));
//            flag = true;
//        }
//        else
//            flag = false;UINT lv = 0;for(int i = 0; i < maxLevel; ++i){if(rand()%2)lv++;}return lv;}
public:UINT maxLevel;skipNode<T> *head;skiplist<T>(UINT level = 10):maxLevel(level){head = new skipNode<T>(level);}~skiplist<T>(){skipNode<T> *p = head, *q;while(p){q = p;p = p->next[0];delete q;}}void insert(const T& inputdata){skipNode<T>* newNode = new skipNode<T>(maxLevel, inputdata);skipNode<T>* temPos[maxLevel+1];skipNode<T> *p = head, *q = NULL;for(int i = maxLevel; i >= 0; i--)  //记录插入点在每层的前一个位置{while((q = p->next[i]) && (q->data <= inputdata)){p = q;}temPos[i] = p;}UINT lv = randomLevel();    //新节点的随机索引级数for(int i = 0; i <= lv; ++i)    //将新节点依次连接进去{newNode->next[i] = temPos[i]->next[i];temPos[i]->next[i] = newNode;}}void delete_node(const T& inputdata){skipNode<T>* temPos[maxLevel+1];skipNode<T> *p = head, *q = NULL;for(int i = maxLevel; i >= 0; i--){while((q = p->next[i]) && (q->data < inputdata)){p = q;}temPos[i] = p;}if(q && q->data == inputdata){for(int i = 0; i <= maxLevel; ++i){if(temPos[i]->next[i] == q)temPos[i]->next[i] = q->next[i];}delete q;q = NULL;}}void printSkipList(){skipNode<T> *p, *q;for(int i = maxLevel; i >= 0; --i){p = head;while(q = p->next[i]){cout << q->data << " -> ";p = q;}cout << endl;}}
};#endif //SKIPLIST_SKIPLIST_H

test_skiplist.cpp

/*** @description: 测试跳表* @author: michael ming* @date: 2019/4/23 0:07* @modified by: */
#include "skiplist.h"
int main()
{skiplist<int> intSList;for(int i = 0; i < 10; ++i){intSList.insert(i);}intSList.printSkipList();intSList.delete_node(9);intSList.printSkipList();intSList.delete_node(100);intSList.printSkipList();return 0;
}

以上写的比较简单,删除多个节点后,索引重新合理重建没有写。应该还有很多需要改进的地方,先放一放,往后继续学,保持学习进度。
测试结果:

数据结构--跳表SkipList相关推荐

  1. 一种数据结构 跳表skiplist

    跳表是平衡树的一种替代的数据结构,但是和红黑树不相同的是,跳表对于树的平衡的实现是基于一种随机化的算法的,这样也就是说跳表的插入和删除的工作是比较简单的. 下载地址 : http://download ...

  2. java数据结构红黑树上旋下旋_存储系统的基本数据结构之一: 跳表 (SkipList)

    在接下来的系列文章中,我们将介绍一系列应用于存储以及IO子系统的数据结构.这些数据结构相互关联又有着巨大的区别,希望我们能够不辱使命的将他们分门别类的介绍清楚.本文为第一节,介绍一个简单而又有用的数据 ...

  3. 每日一博 - 如何理解跳表(SkipList)

    文章目录 什么是跳跃表SkipList 跳表关键字 Why Skip List Code 跳表-查询 跳表-删除 跳表-插入 小结 完整Code 什么是跳跃表SkipList 跳跃表(简称跳表)由美国 ...

  4. java 跳表_数据结构跳表学习并用Java实现

    前面学习很多类的源码过程中,底层基本都是数组和链表,今天学习第三种结构跳表(SkipList). 跳表解决的问题 一个有序的数组如果我们要判断一个数据是否存在可以通过二分查找法非常快速的判断出来,但是 ...

  5. 高阶数据结构 -------- 跳表

    目录 1.什么是跳表 - Skiplist 2.skiplist的效率如何保证? 3.Skiplist实现 (1)整体代码 (2)节点设计 (3) Skiplist成员变量 和 构造函数 (4)sea ...

  6. 跳表-skiplist的简单实现

    文章目录 1.什么是跳表-skiplist 2.skiplist的效率如何保证? 3.skiplist的实现 4.skiplist跟平衡搜索树和哈希表的对比 1.什么是跳表-skiplist skip ...

  7. 为啥 redis 使用 跳表 (skiplist) 而不是使用 red-black?

    基本结论 1.实现简单. 2.区间查找快.跳表可以做到O(logn) 的时间复杂度定位区间的起点,然后在原始链表中顺序往后遍历就可以了. 3.并发环境优势.红黑树在插入和删除的时候可能需要做一些reb ...

  8. 什么是跳表 skiplist ?

    什么是跳表 skiplist ? 文章目录 什么是跳表 skiplist ? 特性 实现 结构 查找 插入 删除 完整代码 参考 跳表可以快速地查找.插入.删除.据说可以替代红黑树.Redis中的有序 ...

  9. Redis数据结构之——跳表skiplist

    写在前面 以下内容是基于Redis 6.2.6 版本整理总结 一.跳表(skiplist) 如何理解跳表?在了解跳表之前,我们先从普通链表开始,一点点揭开跳表的神秘面纱~ 首先,普通单链表来说,即使链 ...

最新文章

  1. python 装饰器参数_python_如何修改装饰器中参数?
  2. 提示YOU DON'T HAVE PERMISSION TO ACCESS / ON THIS的解决方法
  3. Python基础班每日整理(三)
  4. OpenStack neutron中AsyncProcess类
  5. C++ memcpy和memmove实现
  6. 微软OCR两层优化提升自然场景下的文字识别精度(模式识别新研究)
  7. TabHost 和 FragmentTabHost
  8. JavaScript中循环遍历JSON响应!
  9. [NOTE] sqli-labs Basic Challenges
  10. 窗体间的跳转传值 1124
  11. 【模板】高精度 [高精度]
  12. 【优化算法】果蝇算法(FOA)【含Matlab源码 1568期】
  13. 2022李宏毅机器学习hw2
  14. 解决WEPE(微pe)安装win11时这台电脑不符合Windows所需的最低系统要求
  15. Python爬虫五:微信公众号爬虫-2018.9
  16. 风云唐太宗(上部)精要
  17. CAD创建组却没有组合在一起?
  18. 动态内存申请(malloc, calloc, new)之分配虚拟内存空间和物理内存空间
  19. [学习SLAM]VINS中IMU预积分的误差推到公式与代码雅克比(协防差/信息矩阵)构建
  20. linux在vi创建文件,Linux下创建文本文件(vi/vim命令使用详解)

热门文章

  1. linux报网络设备繁忙,【分享】linux常用命令
  2. [Lydsy1805月赛] 对称数
  3. Java:从99瓶子数到0,一个int、String变量、while循环、if条件测试
  4. iOS10 打开APP设置界面和WIFI界面
  5. 60、二叉搜索树的第k个结点
  6. android 应用在启动后进行全局的的初始化操作
  7. VC 6中使用不同调用规范的函数在符号文件里的表示方式
  8. 浅谈 JavaScript 编程语言的编码规范--转载
  9. 开始android旅程
  10. 2009岁末之复用系统框架(B/S)