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

【大数据算法】一文掌握大数据算法之:排序链表搜索的亚线性算法。

排序链表搜索的亚线性算法

  • 1、引言
  • 2、平面图直径问题的亚线性算法
    • 2.1 定义
    • 2.2 核心原理
      • 2.2.1 跳表
      • 2.2.2 跳跃搜索
      • 2.2.3 分块搜索
    • 2.3 应用场景
    • 2.4 算法公式
    • 2.5 代码示例
  • 3、总结

1、引言

小屌丝:鱼哥,这茶味道怎么样?
小鱼:嗯,确实不错?
小屌丝:这时间也差不多了, 我们去泡泡澡?
小鱼:也行,这茶叶,带着。
小屌丝:… 鱼哥,咱这会所有茶啊。
小鱼:别这么小气,你这茶味道不错的。
小屌丝:你这…没喝到这个茶叶之前, 你喝其他的,这味道不也是不错的嘛。
小鱼:要不,咱再等一会?
小屌丝:怎么不着急了?
小鱼:我突然想起来,排序链表搜索的亚线性算法还没跟你说的
小屌丝:这个,我不着急啊。
小鱼:那不行, 学习岂能学一半的时候,
小屌丝:…。
小鱼:这茶,再冲泡一次。
小屌丝:…
小鱼:别那么小气。
小屌丝:… 好好好~

在这里插入图片描述

2、平面图直径问题的亚线性算法

2.1 定义

在数据结构中,排序链表是一种链表,其中节点按某种自然顺序排序。

对排序链表进行搜索时,传统线性搜索的时间复杂度是 O ( n ) O(n) O(n),其中 n n n是链表的长度。

亚线性时间算法旨在通过某些特殊技巧和预处理步骤,使搜索操作的时间复杂度低于 O ( n ) O(n) O(n),实现更快的查询速度。

2.2 核心原理

排序链表搜索的亚线性算法主要利用了如下核心原理:

  • 跳表(Skip List):一种层级化的链表结构,增加了多层索引以实现更快的跳跃和搜索。
  • 跳跃搜索(Jump Search):在链表上进行固定长度的跳跃,以减少搜索范围。
  • 分块搜索(Block Search):将链表划分为若干块,每块进行局部排序,再在每块内进行二分查找。

2.2.1 跳表

跳表(Skip List)

  • 跳表是一种层次化的数据结构,允许快速搜索。跳表为普通链表增加了多层“跳跃”链表,每层链表的长度是下层的约一半,通过这些级联的跳跃层,可以快速跳过大量元素。

2.2.2 跳跃搜索

跳跃搜索(Jump Search)

  • 跳跃搜索算法在排序链表上以固定步长跳跃进行搜索,先找到目标值可能存在的区间,再在该区间内进行线性扫描,从而减少搜索的耗时。
  • 假设步长为 k k k,则其时间复杂度为 O ( √ n ) O(√n) O(n)

2.2.3 分块搜索

分块搜索(Block Search)

  • 分块搜索将排序链表划分成若干块,每块内进行局部排序,然后在每块内进行二分查找。
  • 这种方法利用了局部性的优势,实现了更快的搜索速度。

2.3 应用场景

平排序链表搜索的亚线性算法在以下场景中具有广泛的应用:

  • 数据库索引:跳表广泛应用于数据库索引结构,如 LevelDB 和 Redis。
  • 搜索引擎:在各种搜索引擎中,跳表用于快速查找和排序。
  • 网络路由:在计算网络路由路径时,跳表有助于快速定位路由信息。
  • 内存缓存:在高速缓存系统中,跳表用于快速存取缓存数据。

2.4 算法公式

以跳表为例,其时间复杂度通常为 O ( l o g n ) O(log n) O(logn),这显著优于传统链表的 O ( n ) O(n) O(n)

跳表算法的索引结构
设节点总数为 n,则跳表的结构通常包括以下几层:

  • 底层:包含所有节点。
  • 上层:每隔 k k k 个节点抽取一个节点 ( k ≈ 2 ) (k ≈ 2) k2
  • 顶层:仅包含几个或一个节点。

各层的节点数大致为 n n n, n / 2 n/2 n/2, n / 4 n/4 n/4, …, 1。

2.5 代码示例

# -*- coding:utf-8 -*-
# @Time   : 2024-08-10
# @Author : Carl_DJimport randomclass SkipListNode:def __init__(self, value, level):self.value = valueself.forward = [None] * (level + 1)class SkipList:def __init__(self, max_level):self.max_level = max_levelself.header = SkipListNode(None, max_level)self.level = 0def random_level(self):level = 0while random.random() < 0.5 and level < self.max_level:level += 1return leveldef insert(self, value):update = [None] * (self.max_level + 1)current = self.headerfor i in range(self.level, -1, -1):while current.forward[i] and current.forward[i].value < value:current = current.forward[i]update[i] = currentlevel = self.random_level()if level > self.level:for i in range(self.level + 1, level + 1):update[i] = self.headerself.level = levelnew_node = SkipListNode(value, level)for i in range(level + 1):new_node.forward[i] = update[i].forward[i]update[i].forward[i] = new_nodedef search(self, value):current = self.headerfor i in range(self.level, -1, -1):while current.forward[i] and current.forward[i].value < value:current = current.forward[i]current = current.forward[0]return current and current.value == value# 示例使用
skiplist = SkipList(max_level=4)
values = [1, 3, 7, 8, 9, 10, 13, 14, 19]
for value in values:skiplist.insert(value)# 搜索
search_value = 10
found = skiplist.search(search_value)
print(f"Value {search_value} {'found' if found else 'not found'} in the skiplist")

代码解析

  • SkipListNode 类定义了跳表节点,每个节点包含一个值和一个 forward 数组,表示该节点的跳跃层。
  • SkipList 类定义了跳表的数据结构和基本操作,包括插入和搜索。
  • random_level 方法定义了一个基于随机数的层级选择机制,符合跳表的性质。
  • insert 方法插入一个新值到跳表中,动态调整跳表的层级。
  • search 方法在跳表中搜索一个值,利用多层索引快速定位。

在这里插入图片描述

3、总结

排序链表搜索的亚线性算法通过多层索引、固定步长跳跃、以及分块搜索等技术,显著降低了搜索时间复杂度。

跳表作为一种高效的数据结构,已经证明其在数据库索引、搜索引擎、内存缓存等领域的有效性和广泛应用。

我是小鱼

  • CSDN 博客专家
  • 阿里云 专家博主
  • 51CTO博客专家
  • 企业认证金牌面试官
  • 多个名企认证&特邀讲师等
  • 名企签约职场面试培训、职场规划师
  • 多个国内主流技术社区的认证专家博主
  • 多款主流产品(阿里云等)评测一等奖获得者

关注小鱼,学习【大数据算法】领域最新最全的领域知识。

相关文章:

  • 北京网站建设多少钱?
  • 辽宁网页制作哪家好_网站建设
  • 高端品牌网站建设_汉中网站制作
  • 服务容错(Service Fault Tolerance)
  • Git 版本控制操作
  • 鲲鹏服务器安装Kafka
  • C#二叉搜索树算法
  • 数据库查询优化:提高数据提取效率
  • 趋势分享|Gartner解读中国企业容器管理新挑战:混合环境、容器安全、AI支持
  • 网络缓存:加速网络应用的隐形引擎
  • 如何在 Ubuntu 系统中安装PyCharm集成开发环境?
  • Java—Arrays api
  • P2730 [USACO3.2] 魔板 Magic Squares
  • 今日总结:巧用setTimeout()方法来制造局部刷新效果
  • MySQL学习笔记之用户管理与权限控制(DCL)
  • Android常见界面控件(三)
  • 云计算第二阶段---DBA Day05-DAY07
  • 解决方案:在jupyter notebook环境下安装不了numpy
  • Docker: 容器互访的三种方式
  • Docker容器管理
  • EOS是什么
  • Python3爬取英雄联盟英雄皮肤大图
  • 理清楚Vue的结构
  • 每个JavaScript开发人员应阅读的书【1】 - JavaScript: The Good Parts
  • 前端设计模式
  • 深入 Nginx 之配置篇
  • 译有关态射的一切
  • 这几个编码小技巧将令你 PHP 代码更加简洁
  • 正则与JS中的正则
  • 400多位云计算专家和开发者,加入了同一个组织 ...
  • ionic异常记录
  • LIGO、Virgo第三轮探测告捷,同时探测到一对黑洞合并产生的引力波事件 ...
  • ​业务双活的数据切换思路设计(下)
  • #NOIP 2014# day.2 T2 寻找道路
  • (k8s中)docker netty OOM问题记录
  • (LNMP) How To Install Linux, nginx, MySQL, PHP
  • (Matalb时序预测)WOA-BP鲸鱼算法优化BP神经网络的多维时序回归预测
  • (PySpark)RDD实验实战——取最大数出现的次数
  • (第二周)效能测试
  • (分享)一个图片添加水印的小demo的页面,可自定义样式
  • (三)mysql_MYSQL(三)
  • (转)使用VMware vSphere标准交换机设置网络连接
  • .gitignore文件—git忽略文件
  • .net 7和core版 SignalR
  • .net core + vue 搭建前后端分离的框架
  • .Net Core 微服务之Consul(二)-集群搭建
  • .net core使用RPC方式进行高效的HTTP服务访问
  • .NET实现之(自动更新)
  • @staticmethod和@classmethod的作用与区别
  • @软考考生,这份软考高分攻略你须知道
  • [AI 大模型] Meta LLaMA-2
  • [AI]文心一言出圈的同时,NLP处理下的ChatGPT-4.5最新资讯
  • [autojs]autojs开关按钮的简单使用
  • [C#]winform部署yolov9的onnx模型
  • [C/C++] -- 二叉树
  • [C语言]——函数递归
  • [Django开源学习 1]django-vue-admin
  • [echarts] y轴不显示0