跳跃表原理

简介: 跳跃表原理

跳跃表


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

跳表这种特殊的数据结果是有 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) {
    }
}


相关文章
|
3月前
|
算法 架构师 NoSQL
【数据结构之红黑树】深入原理与实现
意节点的左子树和右子树的层高差不大于1,为了维护树的平衡,我们介绍了树的左右旋转。但是,AVL树维护平衡的代价是比较大的。所以,我们又介绍了红黑树这种数据结构,这是因为红黑树插入的效率相对AVL树是比较高的,在统计意义上来讲红黑树在插入和查找综合上效率是比较高的,这也是为什么红黑树为什么广泛应用在计算机各个方面。
30 2
|
存储 NoSQL 算法
跳表
跳表
112 0
|
4月前
|
NoSQL 算法 Java
数据结构之跳表理解
数据结构之跳表理解
86 0
|
存储 数据库 索引
跳表问题的探讨
跳表是一种高效的数据结构,它可以在有序链表上进行快速的搜索、插入、删除操作,时间复杂度为O(log n)。本文将介绍跳表的原理、实现方式以及其在实际应用中的优势和局限性。
141 0
【数据结构】单向链表的原理及实现
【数据结构】单向链表的原理及实现
【数据结构】单向链表的原理及实现
|
NoSQL Redis 索引
【数据结构】跳表
【数据结构】跳表
64 0
|
存储 算法 NoSQL
每日一博 - 如何理解跳表(SkipList)
每日一博 - 如何理解跳表(SkipList)
76 0
|
存储 算法 NoSQL
常见数据结构-跳表
常见数据结构-跳表
107 0
|
存储 算法 NoSQL
比红黑树更快的跳表到底是什么数据结构?如何实现?
比红黑树更快的跳表到底是什么数据结构?如何实现?
比红黑树更快的跳表到底是什么数据结构?如何实现?
|
NoSQL Redis
跳跃表介绍
有序集合在生活中比较常见,例如根据成绩对学生排名,根据得分对玩家排名等。对于有序集合的底层实现,可以用数组、平衡树、链表等。数组不便元素的插入、删除;平衡树或红黑树虽然效率高但结构复杂;链表查询需要遍历所有效率低。
跳跃表介绍