当前位置: 首页 > news >正文

跳表的C语言实现

跳表(Skip List)是一种基于链表的动态数据结构,用于实现高效的查找、插入和删除操作。它通过引入多级索引来加速查找过程,类似于多级索引的有序链表。跳表的平均时间复杂度为 O(logn),在某些场景下可以替代平衡树。

以下是跳表的基本实现思路和一个简单的 C 语言实现示例。


1. 跳表的基本概念

  • 节点结构:每个节点包含一个值和多个指向不同层级的指针。

  • 层级:每个节点的层级是随机的,通常通过抛硬币的方式决定。层级越高,索引的作用越强。

  • 头节点:跳表的入口,包含指向各级索引的指针。

  • 尾节点(可选):用于快速判断是否到达链表末尾。


2. 跳表的关键操作

  1. 查找:从最高层开始,逐层向下查找,直到找到目标值或到达底层。

  2. 插入:找到插入位置后,随机生成节点的层级,并更新指针。

  3. 删除:找到目标节点后,更新相关指针,并释放节点。


3. C语言实现

以下是一个简单的跳表实现,支持查找、插入和删除操作:

#include <stdio.h>
#include <stdlib.h>
#include <time.h>#define MAX_LEVEL 16  // 最大层级
#define PROBABILITY 0.5  // 随机层级的概率typedef struct SkipListNode {int value;struct SkipListNode* next[MAX_LEVEL];
} SkipListNode;typedef struct SkipList {SkipListNode* head;int level;
} SkipList;// 创建新节点
SkipListNode* createNode(int value, int level) {SkipListNode* node = (SkipListNode*)malloc(sizeof(SkipListNode));node->value = value;for (int i = 0; i < level; i++) {node->next[i] = NULL;}return node;
}// 创建跳表
SkipList* createSkipList() {SkipList* list = (SkipList*)malloc(sizeof(SkipList));list->head = createNode(-1, MAX_LEVEL);  // 创建头节点list->level = 0;return list;
}// 随机生成层级
int randomLevel() {int level = 1;while (rand() / (double)RAND_MAX < PROBABILITY && level < MAX_LEVEL) {level++;}return level;
}// 查找操作
SkipListNode* search(SkipList* list, int value) {SkipListNode* current = list->head;for (int i = list->level - 1; i >= 0; i--) {while (current->next[i] != NULL && current->next[i]->value < value) {current = current->next[i];}}current = current->next[0];if (current != NULL && current->value == value) {return current;}return NULL;
}// 插入操作
void insert(SkipList* list, int value) {int level = randomLevel();SkipListNode* newNode = createNode(value, level);SkipListNode* update[MAX_LEVEL] = {NULL};SkipListNode* current = list->head;for (int i = list->level - 1; i >= 0; i--) {while (current->next[i] != NULL && current->next[i]->value < value) {current = current->next[i];}update[i] = current;}for (int i = 0; i < level; i++) {newNode->next[i] = update[i]->next[i];update[i]->next[i] = newNode;}if (level > list->level) {for (int i = list->level; i < level; i++) {list->head->next[i] = newNode;}list->level = level;}
}// 删除操作
void deleteNode(SkipList* list, int value) {SkipListNode* update[MAX_LEVEL] = {NULL};SkipListNode* current = list->head;for (int i = list->level - 1; i >= 0; i--) {while (current->next[i] != NULL && current->next[i]->value < value) {current = current->next[i];}update[i] = current;}current = current->next[0];if (current != NULL && current->value == value) {for (int i = 0; i < list->level; i++) {if (update[i]->next[i] != current) {break;}update[i]->next[i] = current->next[i];}free(current);while (list->level > 1 && list->head->next[list->level - 1] == NULL) {list->level--;}}
}// 打印跳表
void printSkipList(SkipList* list) {for (int i = list->level - 1; i >= 0; i--) {SkipListNode* current = list->head->next[i];printf("Level %d: ", i);while (current != NULL) {printf("%d ", current->value);current = current->next[i];}printf("\n");}
}int main() {srand(time(NULL));SkipList* list = createSkipList();insert(list, 3);insert(list, 6);insert(list, 7);insert(list, 9);insert(list, 12);insert(list, 19);insert(list, 17);insert(list, 26);insert(list, 21);insert(list, 25);printf("Skip List:\n");printSkipList(list);SkipListNode* result = search(list, 19);if (result != NULL) {printf("Found %d in the skip list.\n", result->value);} else {printf("Value not found.\n");}deleteNode(list, 19);printf("Skip List after deletion:\n");printSkipList(list);return 0;
}

4. 代码说明

  1. 节点结构:每个节点包含一个值和一个指向不同层级的指针数组。

  2. 随机层级:通过抛硬币的方式决定节点的层级。

  3. 查找:从最高层开始,逐层向下查找。

  4. 插入:找到插入位置后,随机生成节点的层级,并更新相关指针。

  5. 删除:找到目标节点后,更新相关指针,并释放节点。

  6. 打印:逐层打印跳表的内容,方便观察结构。


5. 运行结果

运行程序后,跳表的结构会以多级索引的形式打印出来,查找、插入和删除操作的结果也会显示。


跳表是一种非常灵活的数据结构,适用于需要高效查找和动态更新的场景。希望这个实现对你有所帮助!

相关文章:

跳表的C语言实现

跳表&#xff08;Skip List&#xff09;是一种基于链表的动态数据结构&#xff0c;用于实现高效的查找、插入和删除操作。它通过引入多级索引来加速查找过程&#xff0c;类似于多级索引的有序链表。跳表的平均时间复杂度为 O(logn)&#xff0c;在某些场景下可以替代平衡树。 以…...

Java Web开发实战与项目——Spring Security与权限管理实现

Web应用中&#xff0c;权限管理是系统安全的核心部分&#xff0c;确保用户只能访问他们被授权的资源。Spring Security是Spring框架中的一个安全框架&#xff0c;它提供了强大的认证和授权功能&#xff0c;用于实现用户认证和权限控制。本章节将详细讲解如何使用Spring Securit…...

单元测试方法的使用

import java.util.Date; import org.junit.Test; /** java中的JUnit单元测试* * 步骤:* 1.选中当前项目工程 --》 右键:build path --》 add libraries --》 JUnit 4 --》 下一步* 2.创建一个Java类进行单元测试。* 此时的Java类要求:①此类是公共的 ②此类提供一个公共的无参…...

VScode内接入deepseek包过程(本地部署版包会)

目录 1. 首先得有vscode软件 2. 在我们的电脑本地已经部署了ollama&#xff0c;我将以qwen作为实验例子 3. 在vscode上的扩展商店下载continue 4. 下载完成后&#xff0c;依次点击添加模型 5. 在这里可以添加&#xff0c;各种各样的模型&#xff0c;选择我们的ollama 6. 选…...

flink写入hdfs数据如何保证幂等的?

在 Flink 中使用 HDFS Connector 将数据写入 HDFS 时&#xff0c;保证幂等性是一个重要的需求&#xff0c;尤其是在数据可靠性要求较高的场景下。以下是详细介绍如何通过 Flink 和 HDFS 的特性以及一些设计上的优化来实现幂等性。 一、Flink 的 Checkpoint 机制 Flink 的 Chec…...

newgrp docker需要每次刷新问题

每次都需要运行 newgrp docker 的原因: 当用户被添加到 docker 组后&#xff0c;当前会话并不会立即更新组信息&#xff0c;因此需要通过 newgrp docker 切换到新的用户组以使权限生效 如果不想每次都手动运行 newgrp docker&#xff0c;可以在终端中配置一个自动刷新的脚本。…...

LM_Funny-2-01 递推算法:从数学基础到跨学科应用

目录 第一章 递推算法的数学本质 1.1 形式化定义与公理化体系 定理1.1 (完备性条件) 1.2 高阶递推的特征分析 案例&#xff1a;Gauss同余递推4 第二章 工程实现优化技术 2.1 内存压缩的革新方法 滚动窗口策略 分块存储技术 2.2 异构计算加速方案 GPU并行递推 量子计…...

WDM_OTN_基础知识_波分站点与组网类型

为了便于理解&#xff0c;我们用高铁来打个比方&#xff0c;这是郑州与武汉的高铁&#xff0c;中间经过了许昌孝感等很多个站点&#xff0c;郑州武汉作为始发站和终点站&#xff0c;所有人员都是上车或下车&#xff0c;而许昌等中间站点&#xff0c;既有人员上下车&#xff0c;…...

机器视觉--索贝尔滤波

引言 在图像处理领域&#xff0c;边缘检测是一项至关重要的任务&#xff0c;它能够帮助我们识别图像中不同区域的边界&#xff0c;为后续的目标识别、图像分割等操作奠定基础。索贝尔滤波&#xff08;Sobel Filter&#xff09;作为一种经典的边缘检测算法&#xff0c;因其简单…...

网络分析仪E5071C的回波损耗测量

回波损耗&#xff08;Return Loss&#xff09;是评估射频/微波元件&#xff08;如滤波器、天线、电缆等&#xff09;信号反射特性的关键参数&#xff0c;反映端口阻抗匹配性能。E5071C矢量网络分析仪&#xff08;VNA&#xff09;通过以下步骤实现高精度回波损耗测量&#xff1a…...

力扣-二叉树-98 验证二叉搜索树

思路 第一个特性&#xff0c;二叉搜索树的中序遍历是有序的&#xff0c;第二个特性&#xff0c;利用两个指针判断大小关系 代码 class Solution { public:TreeNode* pre NULL;bool isValidBST(TreeNode* root) {if(root NULL) return true;bool left isValidBST(root->…...

【动态规划】详解 0-1背包问题

文章目录 1. 问题引入2. 从 dfs 到动态规划3. 动态规划过程分析4. 二维 dp 的遍历顺序5. 从二维数组到一维数组6. 一维数组的遍历次序7. 背包的遍历顺序8. 代码总结9. 总结 1. 问题引入 0-1 背包是比较经典的动态规划问题&#xff0c;这里以代码随想录里面的例子来介绍下。总的…...

【Java线程池与线程状态】线程池分类与最佳实践

解析Java线程池与线程状态变化&#xff0c;结合运行机制与业务场景对照&#xff0c;帮助形成系统性知识。 一、线程池核心要素&#xff08;五维模型&#xff09; 采用「参数配置→处理流程→工作模式」三层递进结构 核心参数&#xff08;线程池DNA&#xff09; corePoolSiz…...

【小白学AI系列】NLP 核心知识点(八)多头自注意力机制

文章目录 **多头自注意力机制&#xff08;Multi-Head Self-Attention&#xff09;****核心概念** **1. 自注意力机制&#xff08;Self-Attention&#xff09;****2. 多头机制&#xff08;Multi-Head Attention&#xff09;****3. 为什么要用多头注意力机制&#xff1f;****4. 公…...

学习笔记——word中图目录、表目录 标题引用

目标1&#xff1a; 建立——图1-1 引用——图1-1 1在word文档中的引用——>插入题注 新建标签&#xff0c;然后命名为“图1-“。 点击确认&#xff0c;即可插入如图所示 图1- 1 春天 需要把图1-和后面那个1中间的空格删除&#xff0c;即 图1-1 春天 2怎么去引用这个“…...

3.3 Hugging Face Transformers核心功能模块深度解析

Hugging Face Transformers核心功能模块深度解析 一、模块化架构总览 #mermaid-svg-wxTV5vrEo7Y57IlW {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg-wxTV5vrEo7Y57IlW .error-icon{fill:#552222;}#mermaid-svg-wxT…...

linux中设置脚本定时执行ntp命令同步时间

目录 一、背景二、过程1.到系统目录2.安装ntp3.创建文件夹4.创建脚本文件5.提升脚本文件权限6.设置执行时间&#xff1a;7.检查是否设置了执行器&#xff08;执行后输出的内容为执行器中的定时执行内容&#xff09;8.执行脚本文件9.查看日志文件&#xff0c;是否执行成功 三、总…...

map的使用(c++)

在了解map之前&#xff0c;我们先看看两个场景&#xff0c;通过这两个场景的对比&#xff0c;让我们知道为什么要存在存储双关键字的容器 场景一&#xff1a;判断一堆字符串中&#xff0c;某一个字符串是否出现过 在没学set容器之前&#xff0c;我们只能想到把这一堆字符串存到…...

毕业设计—基于Spring Boot的社区居民健康管理平台的设计与实现

&#x1f393; 毕业设计大揭秘&#xff01;想要源码和文章&#xff1f;快来私信我吧&#xff01; Hey小伙伴们~ &#x1f44b; 毕业季又来啦&#xff01;是不是都在为毕业设计忙得团团转呢&#xff1f;&#x1f914; 别担心&#xff0c;我这里有个小小的福利要分享给你们哦&…...

Python:蟒蛇绘制(一笔画)

一、题目要求 使用turtle库&#xff0c;绘制一个蟒蛇形状的图形。‬ 二、代码展示 # 请在下方开始编写你的代码 import turtle turtle.setup(650,350,200,200) turtle.penup() turtle.fd(-250) turtle.pendown() turtle.pensize(25) turtle.pencolor("purple") turt…...

Labelme2YOLO:机器学习数据预处理中的数据格式转换工具完整指南

Labelme2YOLO&#xff1a;机器学习数据预处理中的数据格式转换工具完整指南 【免费下载链接】Labelme2YOLO Help converting LabelMe Annotation Tool JSON format to YOLO text file format. If youve already marked your segmentation dataset by LabelMe, its easy to use …...

终极免费文档下载指南:kill-doc让你轻松获取百度文库等30+平台学习资源

终极免费文档下载指南&#xff1a;kill-doc让你轻松获取百度文库等30平台学习资源 【免费下载链接】kill-doc 看到经常有小伙伴们需要下载一些免费文档&#xff0c;但是相关网站浏览体验不好各种广告&#xff0c;各种登录验证&#xff0c;需要很多步骤才能下载文档&#xff0c;…...

医疗器械生产物料编码规则概述

医疗器械生产物料编码规则概述 医疗器械生产物料编码是企业管理物料、追踪供应链、确保产品质量的重要工具。编码规则需遵循行业标准&#xff0c;兼顾唯一性、可扩展性和易用性。以下为常见的编码规则设计方法。 编码结构设计 医疗器械物料编码通常采用层级结构&#xff0c;包含…...

C语言类的基本语法详解

1、由C语言的结构体进入到C中的类我们在C语言中当需要定义多个变量的数据集合时&#xff0c;第一时间会想到使用结构体来进行定义&#xff0c;例如我们定义一个学生变量&#xff0c;包含姓名、年龄、性别等信息&#xff0c;代码示例如下:12345struct Student{char name[12];int…...

从GroundingDino推理到Open-GroundingDino训练:我的环境配置与验证集精度为0的踩坑实录

从推理到训练&#xff1a;Open-GroundingDino实战中的环境配置与验证集精度问题深度解析 当我在深夜第三次尝试启动Open-GroundingDino训练脚本时&#xff0c;终端上闪烁的"validation AP: 0.000"让我陷入了沉思。这不是一个简单的环境配置问题&#xff0c;而是一系…...

Ollama部署DeepSeek-R1-Distill-Qwen-7B完整指南:支持中文长文本理解与结构化输出

Ollama部署DeepSeek-R1-Distill-Qwen-7B完整指南&#xff1a;支持中文长文本理解与结构化输出 你是不是也遇到过这样的问题&#xff1a;想找一个能理解中文长文档、还能帮你整理出清晰结构的AI助手&#xff0c;结果发现要么是英文模型对中文支持不好&#xff0c;要么就是处理长…...

联邦学习中的ROC与PR曲线评估优化策略

1. 联邦学习中的评估指标困境在分布式机器学习领域&#xff0c;联邦学习因其隐私保护特性近年来备受关注。但当我们尝试在这种特殊架构下评估模型性能时&#xff0c;传统集中式机器学习的那套评估方法开始显得力不从心。特别是在处理非平衡数据集时&#xff0c;准确率&#xff…...

如何快速检测微信单向好友?WechatRealFriends帮你发现谁悄悄删除了你

如何快速检测微信单向好友&#xff1f;WechatRealFriends帮你发现谁悄悄删除了你 【免费下载链接】WechatRealFriends 微信好友关系一键检测&#xff0c;基于微信ipad协议&#xff0c;看看有没有朋友偷偷删掉或者拉黑你 项目地址: https://gitcode.com/gh_mirrors/we/WechatR…...

PPTist:零门槛构建专业级在线演示文稿的完整解决方案

PPTist&#xff1a;零门槛构建专业级在线演示文稿的完整解决方案 【免费下载链接】PPTist PowerPoint-ist&#xff08;/pauəpɔintist/&#xff09;, An online presentation application that replicates most of the commonly used features of MS PowerPoint, allowing for…...

Samsung三星mlcc片容原厂原装一级代理分销经销批发

品牌 元件类别 型号 描述 包装 数量 SAMSUNG 电容 CL10A105KO8NNNC 0603 1UF 16V 10% X5R 4000 8000,000...