【问题标题】:Insertion into a skip list插入跳过列表
【发布时间】:2014-12-03 22:43:04
【问题描述】:

跳过列表是一种数据结构,其中元素按排序顺序存储,列表的每个节点可能包含多个指针,用于减少搜索所需的时间对于一般情况,从单链表中的O(n)O(lg n) 的操作。它看起来像这样:

参考:Wojciech Muła 的“跳过列表” - 自己的作品。通过 Wikimedia Commons 在公共领域获得许可 - http://commons.wikimedia.org/wiki/File:Skip_list.svg#mediaviewer/File:Skip_list.svg

可以看作是尺子的类比:

在跳过列表中,搜索一个元素并删除一个元素很好,但是插入时就变得困难了,因为根据Data Structures and Algorithms in C++: 2nd edition by Adam Drozdek

要插入一个新元素,刚插入的节点后面的所有节点都必须重组;指针的数量和指针的值必须改变。


我可以由此解释,尽管根据节点插入新元素的可能性来选择具有随机指针数量的节点,但不会创建完美的跳过列表,但当大量元素时它会非常接近它(例如约 900 万)被考虑。

我的问题是:为什么我们不能在一个新节点中插入新元素,根据前一个节点确定它的指针个数,附加到链表的末尾,然后使用高效的排序算法仅对节点中存在的数据进行排序,从而保持跳过列表的完美结构并实现O(lg n)插入复杂度?

编辑:我还没有尝试任何代码,我只是呈现一个视图。仅仅因为实现跳过列表有些困难。对不起。

【问题讨论】:

  • 我不明白为什么插入节点之后的所有节点都需要更改。为什么不像普通链表一样插入并完成它呢?跳过列表不一定需要“快速”跃点之间的间距。

标签: c++ algorithm data-structures


【解决方案1】:

您在这一点上有问题and then use efficient sorting algorithms to sort just the data present in the nodes。对数据进行排序将具有复杂性O(n*lg(n)),因此会增加插入的复杂性。从理论上讲,您可以为每个插入的节点选择“完美”数量的链接,但即使这样做,当您执行删除操作时,完美性也会被“破坏”。使用随机方法足够接近完美的结构以表现良好。

【讨论】:

    【解决方案2】:

    你需要有搜索位置的函数/方法。

    需要做到以下几点:

    1. 如果插入唯一键,则需要定位节点。然后您保留所有内容,只需更改数据(行李)。例如节点->数据=数据。

    2. 如果您允许重复,或者如果未找到密钥,则此函数/方法需要为您提供每个高度(车道)上的前一个节点。然后确定新节点的高度并将其插入到找到的节点之后。

    这是我的 C 实现: https://github.com/nmmmnu/HM2/blob/master/hm_skiplist.c

    您需要检查以下功能:

    static const hm_skiplist_node_t *_hm_skiplist_locate(const hm_skiplist_t *l, const char *key, int complete_evaluation);
    

    它将位置存储在 hm_skiplist_t 结构中。

    complete_evaluation 用于在您需要数据并且不打算插入/删除时节省时间。

    【讨论】:

      【解决方案3】:

      插入节点时无需修改任何后续节点。详情请参阅原论文Skip Lists: A Probabilistic Alternative to Balanced Trees

      我已经从该引用中实现了一个跳过列表,我可以向您保证,我的插入和删除例程不会修改插入点前面的任何节点。

      我没有读过你所指的书,但断章取义,你强调的段落完全是错误的。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2012-08-27
        • 1970-01-01
        • 2014-06-17
        • 1970-01-01
        • 2016-07-30
        相关资源
        最近更新 更多