跳跃表原理

简介: 跳跃表原理

跳跃表


跳表是基于链表的,在链表的基础上加了多层索引结构。

跳表这种特殊的数据结果是有 Willam Pugh  发明的。最早出现在1990 年发表的论文《Skip Lists: A Probabilistic Alternative to Balanced Trees


论文中有个描述:

Skip lists are a data structure that can be used in place of balanced trees.Skip lists use probabilistic balancing rather than strictly enforced balancing and as a result the algorithms for insertion and deletion in skip lists are much simpler and significantly faster than equivalent algorithms for balanced trees.


简单的说,跳表是基于概率型的表。

先看个普通有序链表的结构:

640.png如果要查找  23 那么起码需要比较 2次,查找 43 比较 4次,查找 59 比较 6次。有什么办法解决这个问题呢?容易想到二分搜索。


采用分层链表结构,以一些节点作为索引,


640.png

比如,提取了 14  34 50 72 作为一层链表,查找 59 的时候,就可以通过比较 14 24 50 59 共5次找到 59 来减少查找次数。

如果加一层,基本上就可以采用类似二分的方式进行查找了


640.png

640.png

现在看给完整的 快表插入一个新元素的过程:


640.gif

参考代码:

public class SkipList {
    private static class SkipListNode {
        int data;
        SkipListNode[] next;
        SkipListNode(int d, int level) {
            data = d;
            next = new SkipListNode[level + 1];
        }
    }
    private int maxLevel;
    SkipListNode header;
    private static final int INFINITY = Integer.MAX_VALUE;
    SkipList(int maxLevel) {
        this.maxLevel = maxLevel;
        header = new SkipListNode(0, maxLevel);
        SkipListNode sentinel = new SkipListNode(INFINITY, maxLevel);
        for (int i = 0; i <= maxLevel; i++)
            header.next[i] = sentinel;
    }
    public boolean find(int key) {
        SkipListNode current = header;
        for (int i = maxLevel; i >= 0; i--) {
            SkipListNode next = current.next[i];
            while (next.data < key) {
                current = next;
                next = current.next[i];
            }
        }
        current = current.next[0];
        if (current.data == key)
            return true;
        else
            return false;
    }
    public void insert(int searchKey, int newValue) {
        SkipListNode[] update = new SkipListNode[maxLevel + 1];
        SkipListNode current = header;
        for (int i = maxLevel; i >= 0; i--) {
            SkipListNode next = current.next[i];
            while (next.data < searchKey) {
                current = next;
                next = current.next[i];
            }
            update[i] = current;
        }
        current = current.next[0];
        if (current.data == searchKey)
            current.data = newValue;
        else {
            int v = generateRandomLevel();
            SkipListNode node = new SkipListNode(newValue, maxLevel);
            for (int i = 0; i <= v; i++) {
                node.next[i] = update[i].next[i];
                update[i].next[i] = node;
            }
            update = null;
        }
    }
    private int generateRandomLevel() {
        int newLevel = 0;
        while (newLevel < maxLevel && Math.random() < 0.5)
            newLevel++;
        return newLevel;
    }
    public boolean delete(int searchKey) {
        SkipListNode[] update = new SkipListNode[maxLevel + 1];
        SkipListNode current = header;
        for (int i = maxLevel; i >= 0; i--) {
            SkipListNode next = current.next[i];
            while (next.data < searchKey) {
                current = next;
                next = current.next[i];
            }
            update[i] = current;
        }
        current = current.next[0];
        if (current.data == searchKey) {
            for (int i = 0; i <= maxLevel; i++) {
                if (update[i].next[i] == current) {
                    update[i].next[i] = current.next[i];
                    current.next[i] = null;
                } else
                    current.next[i] = null;
            }
            return true;
        }
        return false;
    }
    public static void main(String[] args) {
    }
}


相关文章
|
弹性计算 Linux 数据库
快速用Discuz搭建论坛网站教程
Discuz! 是全球成熟度最高、覆盖率最大的论坛网站软件系统之一,被200多万网站用户使用,本文教你一步一步快速用阿里云免费的Discuz官方系统搭建论坛网站。
44902 0
|
负载均衡 安全 网络安全
聊一聊负载均衡SLB的DDoS防护
众所周知,DDoS(分布式拒绝服务攻击)攻击是当前互联网上最常见,却最难以防范的一种攻击,其基本原理是黑客通过发动成千上万的肉鸡,在短时间内对被攻击目标发起海量访问,大量占用被攻击目标的服务资源,使得正常的业务访问无法进行,具有危害大、成本低、防范难等特点。
13926 0
|
11月前
|
人工智能 弹性计算 运维
ACK Edge与IDC:高效容器网络通信新突破
本文介绍如何基于ACK Edge以及高效的容器网络插件管理IDC进行容器化。
|
8月前
|
人工智能 自然语言处理 算法
真的要让AGI在2025年降临吗?一场技术狂潮下的冷静思考
近年来,关于通用人工智能(AGI)在2025-2026年实现的言论层出不穷,引发业界热烈讨论与公众期待。尽管AI技术取得显著进展,如GPT系列模型,但距离真正AGI仍有差距。技术突破需时间积累,且面临多步规划、长时记忆等挑战。此外,部分企业夸大宣传误导公众,AGI还涉及伦理风险。因此,我们应保持理性态度,正视技术挑战,推动规范化发展,并鼓励参与相关培训提升竞争力。
|
机器学习/深度学习 自然语言处理 C++
TSMamba:基于Mamba架构的高效时间序列预测基础模型
TSMamba通过其创新的架构设计和训练策略,成功解决了传统时间序列预测模型面临的多个关键问题。
898 4
TSMamba:基于Mamba架构的高效时间序列预测基础模型
|
边缘计算 运维 安全
云上物联网边缘节点:重塑连接智能世界的桥梁
结语 云上物联网边缘节点作为物联网技术的重要组成部分,正以其独特的优势和潜力推动着物联网的快速发展。面对未来的机遇和挑战,我们需要不断创新和完善边缘节点的技术架构和应用模式,推动物联网技术的深度融合和广泛应用,为构建智慧社会贡献力量。
401 0
|
前端开发 API 开发者
Python Web开发者必看!AJAX、Fetch API实战技巧,让前后端交互如丝般顺滑!
在Web开发中,前后端的高效交互是提升用户体验的关键。本文通过一个基于Flask框架的博客系统实战案例,详细介绍了如何使用AJAX和Fetch API实现不刷新页面查看评论的功能。从后端路由设置到前端请求处理,全面展示了这两种技术的应用技巧,帮助Python Web开发者提升项目质量和开发效率。
273 1
|
机器学习/深度学习 人工智能 运维
智能化运维:如何利用AI和机器学习优化IT基础设施管理
随着技术的快速发展,传统的运维方法已无法满足现代企业的需求。本文将深入探讨如何通过人工智能(AI)和机器学习(ML)来革新IT基础设施的管理方式,提升效率并降低成本。我们将从实际案例出发,分析AI与ML在智能监控、故障预测、自动化修复等方面的应用,并讨论实施这些技术时面临的挑战与解决策略。
303 33
|
开发框架 前端开发 JavaScript
ABP框架中一对多,多对多关系的处理以及功能界面的处理(1)
ABP框架中一对多,多对多关系的处理以及功能界面的处理(1)
|
存储 设计模式 缓存
Java instanceof操作符:类型检查的必备工具
Java instanceof操作符:类型检查的必备工具
296 0