Python 算法高级篇:跳跃表和布隆过滤器的应用

news2024/9/29 8:06:26

Python 算法高级篇:跳跃表和布隆过滤器的应用

  • 引言
  • 1. 跳跃表( Skip List )
    • 1.1 跳跃表的基本结构
    • 1.2 跳跃表的操作
    • 1.3 Python 中的跳跃表实现
  • 2. 布隆过滤器( Bloom Filter )
    • 2.1 布隆过滤器的基本结构
    • 2.2 布隆过滤器的操作
    • 2.3 Python 中的布隆过滤器实现
  • 3. 应用示例
    • 3.1 跳跃表的应用
    • 3.2 布隆过滤器的应用
  • 4. 总结

引言

在计算机科学中,数据结构和算法是构建强大应用的基础。本文将介绍两个非常有用的数据结构:跳跃表和布隆过滤器。这些数据结构可以在各种应用中提供高效的数据存储和检索解决方案。

😃😄 ❤️ ❤️ ❤️

1. 跳跃表( Skip List )

跳跃表是一种随机化数据结构,类似于有序链表。跳跃表以有序方式存储元素,并使用多层级别的链表来实现快速查找。这使得在跳跃表中查找元素的时间复杂度为 O ( log n ),与二叉搜索树类似,但它更容易实现。

1.1 跳跃表的基本结构

跳跃表包括多个层级,每个层级都是一个有序链表。最底层的链表包含所有元素,而更高级别的链表则包含较少的元素,以便更快地定位到目标元素。

一个简单的跳跃表可以如下所示:

Level 3: 1 → 3 → 5 → 9
Level 2: 1 → 5
Level 1: 1 → 9
Level 0: 1 → 5 → 9

1.2 跳跃表的操作

跳跃表支持以下操作:

  • 插入:在 O ( log n )时间内插入元素。
  • 删除:在 O ( log n )时间内删除元素。
  • 查找:在 O ( log n )时间内查找元素。

1.3 Python 中的跳跃表实现

以下是一个简单的 Python 实现跳跃表的示例:

import random

class Node:
    def __init__(self, key, level=0):
        """
        跳跃表节点的构造函数。
        
        Args:
        - key: 节点的键值。
        - level: 节点的层级(用于索引层次结构)。
        """
        self.key = key
        self.forward = [None] * (level + 1)

class SkipList:
    def __init__(self, max_level):
        """
        初始化跳跃表。
        
        Args:
        - max_level: 跳跃表的最大层级。
        """
        self.max_level = max_level
        self.header = self.create_node(max_level, None)
        self.level = 0
    
    def create_node(self, level, key):
        """
        创建一个新的节点。
        
        Args:
        - level: 节点的层级。
        - key: 节点的键值。
        
        Returns:
        - 新创建的节点。
        """
        return Node(key, level)

    def random_level(self):
        """
        随机生成节点的层级,用于插入新节点。
        
        Returns:
        - 随机生成的层级。
        """
        level = 0
        while random.random() < 0.5 and level < self.max_level:
            level += 1
        return level

    def insert(self, key):
        """
        在跳跃表中插入一个节点。
        
        Args:
        - key: 要插入的节点的键值。
        """
        update = [None] * (self.max_level + 1)
        current = self.header

        for i in range(self.level, -1, -1):
            while current.forward[i] and current.forward[i].key < key:
                current = current.forward[i]
            update[i] = current

        current = current.forward[0]

        if current is None or current.key != key:
            new_level = self.random_level()
            
            if new_level > self.level:
                for i in range(self.level + 1, new_level + 1):
                    update[i] = self.header
                self.level = new_level

            new_node = self.create_node(new_level, key)

            for i in range(new_level + 1):
                new_node.forward[i] = update[i].forward[i]
                update[i].forward[i] = new_node

    def search(self, key):
        """
        在跳跃表中查找一个节点。
        
        Args:
        - key: 要查找的节点的键值。
        
        Returns:
        - 如果找到,返回节点的键值;否则,返回 None。
        """
        current = self.header

        for i in range(self.level, -1, -1):
            while current.forward[i] and current.forward[i].key < key:
                current = current.forward[i]

        current = current.forward[0]

        if current and current.key == key:
            return current.key
        else:
            return None

    def delete(self, key):
        """
        从跳跃表中删除一个节点。
        
        Args:
        - key: 要删除的节点的键值。
        """
        update = [None] * (self.max_level + 1)
        current = self.header

        for i in range(self.level, -1, -1):
            while current.forward[i] and current.forward[i].key < key:
                current = current.forward[i]
            update[i] = current

        current = current.forward[0]

        if current and current.key == key:
            for i in range(self.level + 1):
                if update[i].forward[i] != current:
                    break
                update[i].forward[i] = current.forward[i]

            while self.level > 0 and self.header.forward[self.level] is None:
                self.level -= 1

# 创建一个最大层级为 4 的跳跃表
skip_list = SkipList(4)

# 插入一些节点
skip_list.insert(1)
skip_list.insert(2)
skip_list.insert(3)
skip_list.insert(5)

# 查找节点
print(skip_list.search(3))  # Output: 3
print(skip_list.search(4))  # Output: None

# 删除节点
skip_list.delete(3)
print(skip_list.search(3))  # Output: None

这个示例展示了如何在 Python 中实现一个基本的跳跃表。跳跃表的每个节点包括一个键值对,以及指向下一个和下面一层节点的指针。

2. 布隆过滤器( Bloom Filter )

布隆过滤器是一种空间高效的概率数据结构,用于快速检查一个元素是否属于一个大型集合。布隆过滤器不存储实际元素,而是使用位数组和多个哈希函数来表示元素的存在与否。它通常用于减少磁盘或内存访问的次数,以提高性能。

2.1 布隆过滤器的基本结构

布隆过滤器包括以下基本组成部分:

  • 一个位数组:通常很大,包含大量位。
  • 多个哈希函数:用于将元素映射到位数组中的多个位置。

2.2 布隆过滤器的操作

布隆过滤器支持以下操作:

  • 插入:将元素映射到位数组中的多个位置,并将相应的位设置为 1
  • 查询:检查元素是否可能存在,即检查所有相关位是否都为 1 。如果有任何一个位为 0 ,元素肯定不存在。
  • 删除:由于布隆过滤器的设计目的是快速检查元素是否存在,通常不支持删除操作。

2.3 Python 中的布隆过滤器实现

以下是一个简单的 Python 示例,展示了如何使用布隆过滤器:

import mmh3
from bitarray import bitarray

class BloomFilter:
    def __init__(self, size, hash_count):
        """
        初始化布隆过滤器。
        
        Args:
        - size: 位数组的大小,决定了布隆过滤器的容量。
        - hash_count: 哈希函数的数量,影响性能和误判率。
        """
        self.size = size
        self.hash_count = hash_count
        self.bit_array = bitarray(size)
        self.bit_array.setall(0)

    def add(self, item):
        """
        向布隆过滤器中添加元素。
        
        Args:
        - item: 要添加的元素。
        """
        for seed in range(self.hash_count):
            # 使用哈希函数计算索引并将相应的位设置为1。
            index = mmh3.hash(item, seed) % self.size
            self.bit_array[index] = 1

    def lookup(self, item):
        """
        查询元素是否存在于布隆过滤器中。
        
        Args:
        - item: 要查询的元素。
        
        Returns:
        - True,如果元素可能存在(存在误判的可能性);False,如果元素肯定不存在。
        """
        for seed in range(self.hash_count):
            index = mmh3.hash(item, seed) % self.size
            if self.bit_array[index] == 0:
                return False
        return True

# 创建一个布隆过滤器
bf = BloomFilter(100, 5)

# 向布隆过滤器中添加元素
bf.add("example")

# 查询元素是否存在于布隆过滤器中
print(bf.lookup("example"))  # Output: True
print(bf.lookup("nonexistent"))  # Output: False

这个示例使用了 MurmurHash3 哈希函数和 bitarray 库来实现一个简单的布隆过滤器。

3. 应用示例

跳跃表和布隆过滤器在许多应用中都有广泛的用途。以下是一些示例:

3.1 跳跃表的应用

  • 数据库索引:跳跃表可用于加速数据库查询,尤其是范围查询。
  • 跳跃表的实现已用于 Redis 等高性能数据库管理系统。
  • 跳跃表用于实现高性能的有序集合数据结构。

3.2 布隆过滤器的应用

  • 网络爬虫:布隆过滤器可用于跟踪已访问的 URL ,以避免重复抓取。
  • 垃圾邮件过滤:布隆过滤器可用于快速确定一封电子邮件是否是垃圾邮件。
  • 缓存穿透保护:布隆过滤器可用于防止缓存穿透,即请求不存在于缓存中的数据。

4. 总结

跳跃表和布隆过滤器是两种强大的数据结构,可用于提高数据存储和检索的效率。跳跃表提供了快速的插入、删除和查找操作,适用于有序数据。布隆过滤器提供了高效的集合成员检查,适用于大型数据集合。

无论你是构建数据库系统、网络应用程序还是搜索引擎,了解这些数据结构和它们的应用都将有助于提高性能和减少资源消耗。希望本文能够帮助你更好地理解和应用跳跃表和布隆过滤器。

[ 专栏推荐 ]
😃 Python 算法初阶:入门篇》😄
❤️【简介】:本课程是针对 Python 初学者设计的算法基础入门课程,涵盖算法概念、时间复杂度、空间复杂度等基础知识。通过实例演示线性搜索、二分搜索等算法,并介绍哈希表、深度优先搜索、广度优先搜索等搜索算法。此课程将为学员提供扎实的 Python 编程基础与算法入门,为解决实际问题打下坚实基础。
在这里插入图片描述

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

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

相关文章

看懂分布式追踪系统原理及实践

前言 在微服务架构中,一次请求往往涉及到多个模块,多个中间件,多台机器的相互协作才能完成。这一系列调用请求中,有些是串行的,有些是并行的,那么如何确定这个请求背后调用了哪些应用,哪些模块,哪些节点及调用的先后顺序?如何定位每个模块的性能问题?本文将为你揭晓…

2023年集成电路还缺人吗?集成电路产业人才供需研讨会

10月20日&#xff0c;移知教育创始人团长受邀参与由ARM举办的《集成电路产业人才供需研讨会》&#xff0c;同样受邀参与的还有上海大学、华东理工大学、华东师范大学、上海工程技术大学、上海人社高级职称评审专家等等&#xff0c;高校负责人以及行业专家应邀参加了本次研讨会。…

JVM工具使用(jstack + jstat + jmap)

jstack&#xff1a; jstack是java虚拟机自带的一种堆栈跟踪工具 命令格式&#xff1a; jstack [-l] pid &#xff08;pid 可以使用jps查看&#xff09; 例&#xff1a;jstack 44076 &>$(date %H%M)_44076.jstack.log 线程状态&#xff1a; NEW&#xff0c;未启动的。…

LIO-SAM算法解析

文章目录 简介算法概述1.点云去畸变1.1 主要功能1.2 主要流程 2.特征提取3.IMU预积分4.地图优化5.算法评估 简介 LIO-SAM在lego-loam的基础上新增了对IMU和GPS的紧耦合&#xff0c;采用一个因子图对位姿进行优化&#xff0c;包括IMU因子&#xff0c;激光里程计因子&#xff0c…

企业如何选择设备管理系统?

1、需求为王&#xff0c;列出你的需求清单 每个企业的设备都不尽相同&#xff0c;自然对设备管理系统的需求也不一样。因此&#xff0c;需要充分明确自己的需求和目标&#xff0c;清晰地列出需求清单&#xff0c;然后再逐一对照供应商的产品功能&#xff0c;看是否满足自身各业…

leetCode 76. 最小覆盖子串 + 滑动窗口 + 图解(详细)

76. 最小覆盖子串 - 力扣&#xff08;LeetCode&#xff09; 给你一个字符串 s 、一个字符串 t 。返回 s 中涵盖 t 所有字符的最小子串。如果 s 中不存在涵盖 t 所有字符的子串&#xff0c;则返回空字符串 "" 注意&#xff1a; 对于 t 中重复字符&#xff0c;我们寻…

【AICFD案例操作】潜艇阻力AI预测分析

AICFD是由天洑软件自主研发的通用智能热流体仿真软件&#xff0c;用于高效解决能源动力、船舶海洋、电子设备和车辆运载等领域复杂的流动和传热问题。软件涵盖了从建模、仿真到结果处理完整仿真分析流程&#xff0c;帮助工业企业建立设计、仿真和优化相结合的一体化流程&#x…

3D开发工具HOOPS:助力Navisworks数据处理与3D模型可视化!

在过去的25年中&#xff0c;Tech Soft 3D一直以其卓越的3D技术不断帮助全球600多家客户实现创新&#xff0c;这些客户包括HEXAGON、SolidWorks、SIEMENS、Aras、ANSYS、AVEVA等各行业领军企业。 该公司拥有四款原生产品&#xff0c;分别是&#xff1a;HOOPS Exchange、HOOPS C…

程序员就业时要考虑什么?

要考虑的事情可多了&#xff0c;但很多毕业生都没有这个意识&#xff0c;光想着把自己给卖了。 我还记得自己刚毕业那年&#xff0c;光想着工资高&#xff0c;结果进了熬夜“大班”——一家外包公司。有项目的时候真不是996这么简单&#xff0c;每天是9126&#xff0c;赶上中秋…

jsp获取数据 jsp直接获取后端数据 获取input选中的值 单选 没 checked属性

let str0${showList}; let str1${showList}; 然后可以通过JSON.parse() 转 获取input选中的值 //goodsType 按类别 goods按货品var oneType $("input[ namecriteria1 ] ").val();//count按数量 totalprice按费用var twoType $("input[ namecriteria2 ] &q…

如何选择合适的全渠道智慧收银解决方案?亿发推荐智能收银一体化系统

在数字化时代&#xff0c;品牌面临着越来越多的挑战和机遇。为了更好地适应市场的变化&#xff0c;提高竞争力&#xff0c;越来越多的企业选择引入新零售经营解决方案&#xff0c;以实现定制化的用户运营&#xff0c;沉淀私域流量池&#xff0c;提升流量的高效转化,形成一个完善…

elementUI 特定分辨率(如1920*1080)下el-row未超出一行却换行

在1920*1080分辨率下&#xff0c; el-col 内容未超出 el-col 宽度&#xff0c;el-col 不足以占据一行&#xff0c;el-row 却自动换行了&#xff08;其他分辨率没有这个问题&#xff09;。 截图&#xff1a; 排查&#xff1a; el-col 内容没有溢出&#xff1b;没有多余的 pad…

一次不接受官方建议导致的事故

记录一下 一次Elasticsearch集群事故分析、排查、处理 背景介绍 事故发生的ElasticSearch集群共有7台机器&#xff1a; 10.163.204.19310.163.204.19410.163.204.19510.163.220.7310.163.220.7410.163.220.22010.163.220.221 其中193、194、195的机器配置一样&#xff0c;具…

Boris FX Mocha Pro 2023:Mac/win全能影像处理神器

Boris FX Mocha Pro 2023是一款广受欢迎的影像处理软件&#xff0c;它凭借其强大的功能和卓越的性能&#xff0c;成为了影视后期、广告制作、动画设计等领域的必备工具。无论您是专业的影视制作人员&#xff0c;还是初入行的新手&#xff0c;Boris FX Mocha Pro 2023都能为您的…

医院安全(不良)事件管理系统源代码(B/S架构):事件全程监管 质量持续改进

医院安全&#xff08;不良&#xff09;事件管理系统采用无责的、自愿的填报不良事件方式&#xff0c;有效地减轻医护人员的思想压力&#xff0c;实现以事件为主要对象&#xff0c;可以自动、及时、实际地反应医院的安全、不良、近失事件的情况&#xff0c;更好地掌握不良事件的…

三、【常用的几种抠图方式二】

文章目录 橡皮擦魔术橡皮擦背景橡皮擦选择被遮住&#xff08;调整边缘&#xff09;主体抠图 橡皮擦 直接擦除图片的像素&#xff0c;或者填充背景色&#xff0c;适用于要求不高的图片。 魔术橡皮擦 擦出颜色相近的内容&#xff0c;适用于主体跟背景颜色相差较大的情况&#x…

conda 实践

1. 环境部署 1.1. 下载 anaconda 安装包 下面这个网址查找自己需要的版本 https://repo.anaconda.com/archive/ 或者手动下载。 wget https://repo.anaconda.com/archive/Anaconda3-5.3.0-Linux-x86_64.sh 1.2. 执行安装程序 #安装依赖&#xff1a; sudo yum install bzip2…

手把手教你入门Three.js(初识篇)

Three.js入门篇 一、Three.js和webGL的介绍二、开发和学习环境三、 三个基本概念1. 场景Scene2. 相机Camera3. 渲染器Renderer 四、三维坐标系五、材质Material六、光源1. 点光源2. 环境光3. 平行光: 七、常见几何体八、渲染器-设置设备像素比九、渲染器-锯齿属性 一、Three.js…

8年经验之谈 —— Redis的性能测试与优化!

Redis作为一种高性能的Key-Value数据库&#xff0c;一直受到众多开发者和企业的青睐。然而&#xff0c;在高并发、大数据存储的应用场景中&#xff0c;如何测试并优化Redis的性能&#xff0c;成为了问题。本文将从测试与优化两个方面来讲解如何达到最优的Redis性能。 一、性能…