leecode 1206|跳表的设计

跳表

跳表,一种链表数据结构,其增删改茶的效率能和平衡树相媲美

leecode1206

可以看上面的那个动画,动画效果很贴切。

我简单讲讲它的机制吧,每个节点不单单是一个,测试好几层,然后同一层的节点和统一节点的next 采用单链表产生联系

最核心的东西在于find

这也是为什么单链表的增删改查,花费开销最多的地方。
在这里插入图片描述

那它是怎么查的?
我们已经知道了跳表的结构了,最底层肯定是最全的,如果暴力最底层,那就和单链表没什么区别了。

它的这个查恰巧结合了跳表的结构,如果在上面某个层找到了节点x 的pre那么接下来的操作都好办了。
那它是怎么找到节点x 的pre呢?
从最上层,依次找该节点的next 知道找到pre 如果在这一层还没找到(因为最后一个节点的next 为nullptr),那么会在这个节点的下一层继续找同层找next。依此类推,最后肯定能找到的。

class Skiplist {
private:static const int MAX_LEVEL = 10;struct Node{int val;std::vector<Node*> ne;Node(int _val, int level):val(_val), ne(level, nullptr){};};int level;Node* head;float probability;int randomLevel(){int lvl = 1;while((float) std::rand() / RAND_MAX < probability && lvl < MAX_LEVEL){lvl++;}return lvl;}void find(int t, std::vector<Node*>& ns){Node* cur = head;for(int i = level - 1; i >= 0; i--){while(cur->ne[i] != nullptr && cur->ne[i]->val < t){cur = cur->ne[i];}ns[i] = cur;}}
public:Skiplist() :level(MAX_LEVEL), head(new Node(-1, MAX_LEVEL)), probability(0.5){std::srand(std::time(0));}bool search(int t) {std::vector<Node*> ns(level, nullptr);find(t, ns);Node* target = ns[0]->ne[0];return target != nullptr && target->val == t;}void add(int t) {std::vector<Node*> ns(level, nullptr);find(t, ns);int nodeLevel = randomLevel();Node* newNode = new Node(t, nodeLevel);for(int i = 0; i < nodeLevel; i++){newNode->ne[i] = ns[i]->ne[i];ns[i]->ne[i] = newNode;}}bool erase(int t) {std::vector<Node*> ns(level, nullptr);find(t, ns);Node* target = ns[0]->ne[0];if(target == nullptr || target->val != t){return false;}for(int i = 0; i < level && ns[i]->ne[i] == target; i++){ns[i]->ne[i] = ns[i]->ne[i]->ne[i];}delete target;return true;}~Skiplist(){Node* cur = head;while(cur){Node* next = cur->ne[0];delete cur;cur = next;}}
};/*** Your Skiplist object will be instantiated and called as such:* Skiplist* obj = new Skiplist();* bool param_1 = obj->search(target);* obj->add(num);* bool param_3 = obj->erase(num);*/

再贴一份,

#include <iostream>
#include <vector>
#include <cstdlib>
#include <ctime>class Skiplist {
private:static const int MAX_LEVEL = 10;struct Node {int val;std::vector<Node*> ne;Node(int _val, int level) : val(_val), ne(level, nullptr) {}};int level;Node* head;float probability;int randomLevel() {int lvl = 1;while ((float)std::rand() / RAND_MAX < probability && lvl < MAX_LEVEL) {lvl++;}return lvl;}void find(int t, std::vector<Node*>& ns) {Node* cur = head;for (int i = level - 1; i >= 0; i--) {while (cur->ne[i] != nullptr && cur->ne[i]->val < t) {cur = cur->ne[i];}ns[i] = cur;}}public:Skiplist() : level(MAX_LEVEL), head(new Node(-1, MAX_LEVEL)), probability(0.5) {std::srand(std::time(0));}bool search(int t) {std::vector<Node*> ns(level, nullptr);find(t, ns);Node* target = ns[0]->ne[0];return target != nullptr && target->val == t;}void add(int t) {std::vector<Node*> ns(level, nullptr);find(t, ns);int nodeLevel = randomLevel();Node* newNode = new Node(t, nodeLevel);for (int i = 0; i < nodeLevel; i++) {newNode->ne[i] = ns[i]->ne[i];ns[i]->ne[i] = newNode;}}bool erase(int t) {std::vector<Node*> ns(level, nullptr);find(t, ns);Node* target = ns[0]->ne[0];if (target == nullptr || target->val != t) {return false;}for (int i = 0; i < level && ns[i]->ne[i] == target; i++) {ns[i]->ne[i] = ns[i]->ne[i]->ne[i];}delete target;return true;}~Skiplist() {Node* cur = head;while (cur) {Node* next = cur->ne[0];delete cur;cur = next;}}
};int main() {Skiplist skiplist;skiplist.add(1);skiplist.add(2);skiplist.add(3);std::cout << skiplist.search(1) << std::endl;  // returns truestd::cout << skiplist.search(4) << std::endl;  // returns falseskiplist.add(4);std::cout << skiplist.search(4) << std::endl;  // returns truestd::cout << skiplist.erase(4) << std::endl;   // returns truestd::cout << skiplist.search(4) << std::endl;  // returns falsereturn 0;
}

redis

参考

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/pingmian/15616.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Tomcat部署项目的方式

目录 1、Tomcat发布项目的方式 方式1&#xff1a; 直接把项目发布到webapps目录下 方式2&#xff1a;项目发布到ROOT目录 方式3&#xff1a;虚拟路径方式发布项目 方式4&#xff1a;(推荐)虚拟路径&#xff0c;另外的方式&#xff01; 方式5&#xff1a;发布多个网站 1、…

python从入门到精通04

一、编写英文月份词典 month_num int(input("请输入您想要查询的月份&#xff1a;")) month_list [January,February,March,April,May,June,July,August,September,October,November,December] print("您查询的月份单词是&#xff1a;", month_list[mon…

掩码生成蒸馏——知识蒸馏

摘要 https://arxiv.org/pdf/2205.01529 知识蒸馏已成功应用于各种任务。当前的蒸馏算法通常通过模仿教师的输出来提高学生的性能。本文表明&#xff0c;教师还可以通过指导学生的特征恢复来提高学生的表示能力。从这一观点出发&#xff0c;我们提出了掩码生成蒸馏&#xff08…

【字典树(前缀树) 异或 离线查询】1707. 与数组中元素的最大异或值

本文涉及知识点 字典树&#xff08;前缀树&#xff09; 位运算 异或 离线查询 LeetCode1707. 与数组中元素的最大异或值 给你一个由非负整数组成的数组 nums 。另有一个查询数组 queries &#xff0c;其中 queries[i] [xi, mi] 。 第 i 个查询的答案是 xi 和任何 nums 数组…

戴尔台式机win10家庭版操作系统,插上耳机之后听不到声音。(成功解决)

问题描述 戴尔台式机win10家庭版操作系统&#xff0c;外放有声音&#xff0c;插上耳机之后只有滋啦滋啦的声音&#xff0c;听不到音乐&#xff0c;耳机无损坏&#xff08;在其他台式机和手机上都能听到声音&#xff09;。尝试解决办法如下。 尝试解决 尝试一&#xff1a;更新…

C++ | Leetcode C++题解之第97题交错字符串

题目&#xff1a; 题解&#xff1a; class Solution { public:bool isInterleave(string s1, string s2, string s3) {auto f vector <int> (s2.size() 1, false);int n s1.size(), m s2.size(), t s3.size();if (n m ! t) {return false;}f[0] true;for (int i …

264 基于matlab的自适应语音盲分离

基于matlab的自适应语音盲分离&#xff0c;当a和b同时对着传声器A,B说话且传声器靠得很近时&#xff0c;传声器A,B会同时接受到a和b的声音&#xff0c;即a和b产生了混叠干扰&#xff0c;此时通过自适应语音盲分离系统可以将a,b的声音分离开&#xff0c;使得一个信道只有一个人的…

2024.05.25学习记录

1、面经复习&#xff1a; JS异步进阶、vue-react-diff、vue-router模式、requestldleCallback、React Fiber 2、代码随想录刷题、动态规划 3、组件库使用storybook

这是一个逗号

还不太能是句号&#xff0c;随想录这两个月算是给我一个学算法的开头&#xff0c;感慨还是挺多的&#xff0c;但是语文功底很差&#xff0c;就接着写流水账吧。 高考前想报计算机&#xff0c;但是那年是先报志愿后考试&#xff0c;家里人劝我选择更稳一点的985&#xff0c;又说…

Django的视图层——1HttpResponse对象详解

在django.http模块中定义了HttpResponse对象的APIHttpRequest对象由Django自动创建&#xff0c;HttpResponse对象由程序员创建在每一个视图函数中必须返回一个HttpResponse对象,当然也可以是HttpResponse子对象 1.不用模板,直接返回数据 from django.http import HttpRespons…

RAG与SFT技术简介

RAG与SFT技术简介 1. 检索增强生成&#xff08;RAG&#xff09;1.1 RAG技术的基本概念1.2 RAG的工作流程1.2.1检索阶段1.2.2 生成阶段 1.3 RAG的优势1.4 应用场景 2. 指令微调&#xff08;SFT&#xff09;2.1 SFT技术的基本概念2.2 SFT的工作流程2.2.1 预训练模型2.2.2 微调阶段…

常见的网站业务 + 小程序 + 公众号

1.PC网站 ①公司产品宣传网站&#xff08;比如闲鱼助手、xx软件使用的教程网等等&#xff09; ②知识付费网课网站 2.微信小程序 ①商城类(卖衣服、卖酒、卖鞋、卖女生包包、日用百货、数码商城) ②资讯类(房屋装修咨询、汽车租凭咨询、医美容院、上门回收旧东西、电脑上门维…

xplorer软件和Tauri框架

先上结论&#xff0c;FreeBSD下没调通&#xff0c;因为源代码下载之后不知道该怎么进行下一步..... xplorer软件介绍 XPlorer是一款功能丰富、操作便捷的文件管理软件&#xff0c;它以其多页签功能、双窗格界面、标签式浏览、高级搜索功能以及文件比较工具等特点&#xff0c;赢…

TypeScript 学习笔记(十四):TypeScript 的工具和生态系统

TypeScript 学习笔记(十四):TypeScript 的工具和生态系统 1. 引言 在前几篇学习笔记中,我们探讨了 TypeScript 的基础知识、前后端框架的结合应用、测试与调试技巧、数据库、GraphQL、微服务架构、DevOps 和前端开发的高级应用。本篇将重点介绍 TypeScript 的工具和生态系…

python抽取pdf中的参考文献

想将一份 pdf 论文中的所有参考文献都提取出来&#xff0c;去掉不必要的换行&#xff0c;放入一个 text 文件&#xff0c;方便复制。其引用是 ieee 格式的&#xff0c;形如&#xff1a; 想要只在引用序号&#xff08;如 [3]&#xff09;前换行&#xff0c;其它换行都去掉&…

VTK 数据处理:特征边提取

VTK 数据处理&#xff1a;特征边提取 VTK 数据处理&#xff1a;特征边提取原理实例 1&#xff1a;边界边提取实例 2&#xff1a;模型特征边提取实例 3&#xff1a;利用 vtkFeatureEdges 提取的边界补洞实例 4&#xff1a;利用 vtkFillHolesFilter 补洞 VTK 数据处理&#xff1a…

OC属性关键字和单例模式

OC的属性关键字和单例模式 文章目录 OC的属性关键字和单例模式单例模式基本创建重写allocWithZone方法的同时使用dispatch_once 属性和属性关键字property和synthesize&#xff0c;dynamic属性关键字atomic和nonatomicstrong和weakreadonly和readwritestrong和copy 单例模式 单…

Python期末复习知识点大合集(期末不挂科版)

Python期末复习知识点大合集&#xff08;期末不挂科版&#xff09; 引言 Python是一种高级的、解释型的编程语言&#xff0c;以其清晰的语法和强大的功能而广受欢迎。为了帮助你在Python期末考试中取得优异的成绩&#xff0c;本文将为你提供一个全面的复习知识点合集。 基础…

一千题,No.0018(DFS)

小艾维卡每天都会解决填字游戏。如果你还没有看到&#xff0c;纵横字谜从一个由RC方块组成的网格开始&#xff0c;每个方块要么是空的&#xff0c;要么是阻塞的。玩家的任务是在垂直&#xff08;自上而下&#xff09;或水平&#xff08;从左到右&#xff09;的连续空白方块中书…

MySQL--存储引擎

一、存储引擎介绍 1.介绍 存储引擎相当于Linux的文件系统&#xff0c;以插件的模式存在&#xff0c;是作用在表的一种属性 2.MySQL中的存储引擎类型 InnoDB、MyISAM、CSV、Memory 3.InnoDB核心特性的介绍 聚簇索引、事务、MVCC多版本并发控制、行级锁、外键、AHI、主从复制特…