【问题标题】:Is it any way to implement a linked list with indexed access too?是否也有任何方法可以实现具有索引访问的链表?
【发布时间】:2009-11-28 16:55:54
【问题描述】:

我需要某种链表结构,但如果它也有索引访问,那就太好了。

有没有办法做到这一点?

编辑:我用 C 编写,但它可能适用于任何语言。

【问题讨论】:

  • 各种平台都有这个,e.g. java的java.util.Linkedlist。去看看吧。
  • 我认为他的意思是索引需要相当快。 java.util.LinkedList 有 O(n) 索引。
  • 你的意思是每次添加/删除索引都会改变,对吧?
  • 很多人为这个人发帖,他没有礼貌地接受答案。

标签: language-agnostic data-structures indexing linked-list


【解决方案1】:

实现目标的一种方法是实现随机或确定性skip list。在底层 - 你有你的项目的链接列表。

为了使用索引获取元素,您需要向内部节点添加信息 - 有多少节点处于最低级别,从该节点到该级别的下一个节点。可以在 O(logn) 中添加和维护此信息。

这个解决方案的复杂性是: 添加、删除、转到索引,都在 O(logn) 中工作。

这个解决方案的缺点是它比常规链表更难实现。因此,使用常规链表,您可以在 O(1) 中获得 Add、Remove,并在 O(n) 中获得 Go to index。

【讨论】:

  • 比普通链表更难实现,但比链接节点的平衡树更容易实现。得到我的投票。
  • +1。我不确定如何让跳过列表正确索引。但是现在我突然想到,skiplist 只是一种自动平衡树的形式,因此您可以使用相同的基本节点计数结构。
【解决方案2】:

您可能可以将一棵树用于您的目标。制作一棵二叉树,维护树的每个节点的权重(其中权重等于连接到该节点的节点数,包括自身)。如果你有一个可用于树的平衡方案,那么插入仍然是 O(log n),因为你只需要在祖先节点的权重上加一个。通过索引获取节点是 O(log n),因为您只需要查看所需节点的祖先的索引以及每个祖先的两个子节点。

【讨论】:

  • +1 这是一个很好的答案。我看到的一个问题是数据结构是根据不清楚的东西排序的(也就是“在这个节点之后插入”)。仍然需要弄清楚如何平衡一棵树,以便保留此属性。它不应该太难(例如 2-3 棵树),但它确实不同于常规的平衡树,后者的键决定什么位于何处。
  • 是的,这绝对是个问题。我想你会把实际数据放在他们自己的链表的底部,树的所有内部节点都只包含权重。我在研究生院学到的一种算法是让树(和任何子树)单独放置,直到一侧的权重是另一侧的 N 倍。如果此属性在插入或删除后对任何子树都成立,则为最高的此类子树重建树。这平均维持 O(log n) 时间。
【解决方案3】:

为了在 C++、Java、Python 等语言中实现类似数组的索引,必须为实现链表数据结构的类重载数组索引运算符 []。实现将是 O(n)。在 C 中,由于运算符重载是不可能的,因此必须编写一个函数,该函数采用链表数据结构和一个位置并返回相应的对象。

如果需要更快的订单访问,则必须使用不同的数据结构,例如 jprete 建议的 BTree 或动态数组(当添加新元素时它会自动增长)。一个简单的例子是 C++ 标准库中的std::vector

【讨论】:

    【解决方案4】:

    clustered index are arranged like so 中的 SQL 服务器行项:

       .
     /  \   
    /\  /\  
    *-*-*-*
    

    链表在叶子(*-*-*)中。链表是有序的,允许快速定向扫描,树充当链表的“路线图”。因此,您需要为您的项目提供一个键值对,然后是一个封装树和链表的数据结构。

    所以你的数据结构可能看起来像这样:

    struct ll_node
    {
         kv_pair current;
         ll_node * next;
    };
    
    struct tree_node
    {
       value_type value;
       short isLeaf;        
    
       union
       {
          tree_node * left_child;
          kv_pair * left_leaf;
       }
       union
       {
          tree_node * right_child;
          kv_pair * right_leaf
       }
    };
    
    struct indexed_ll
    {
        tree_node * tree_root;
        ll_node * linked_list_tail;
    };
    

    【讨论】:

      猜你喜欢
      • 2010-12-15
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-09-30
      • 2012-01-26
      • 2023-04-10
      • 2016-06-08
      • 2019-03-26
      相关资源
      最近更新 更多