插入跳过列表

时间:2014-10-09 05:34:39

标签: c++ algorithm data-structures

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

Skip List

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

可以看作是对统治者的类比:

Ruler markings

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

  

要插入新元素,必须重新构建刚刚插入的节点之后的所有节点;必须更改指针的数量和指针的值。


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

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

编辑:我还没有尝试过任何代码,我只是提出一个视图。仅仅因为实现跳过列表有点困难。遗憾。

3 个答案:

答案 0 :(得分:0)

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

答案 1 :(得分:0)

您需要具有搜索位置的功能/方法。

需要做以下事情:

  1. 如果插入唯一键,则需要找到该节点。然后你保留一切,只需更改数据(行李)。例如node-> data = data。

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

  3. 这是我的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 struct中。

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

答案 2 :(得分:0)

插入节点时无需修改任何后续节点。有关详细信息,请参阅原始论文Skip Lists: A Probabilistic Alternative to Balanced Trees

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

我还没有读过你所指的那本书,但是在你没有注意到的情况下,你所强调的这段话是错误的。