Data structures 为添加项(在列表末尾)、迭代和删除项而优化的数据结构

Data structures 为添加项(在列表末尾)、迭代和删除项而优化的数据结构,data-structures,Data Structures,我需要一个数据结构,它将以性能的方式支持以下操作: 将项目添加到列表末尾 按项目添加到列表中的顺序遍历列表(随机访问并不重要) 从列表中删除项目 我应该使用什么类型的数据结构?(我将在下面发布我目前所想的答案。)你应该使用链接列表。将项目添加到列表末尾是O(1)。迭代很容易,您也可以从O(1)中列表中的任何已知位置删除项目。您应该使用链接列表。将项目添加到列表末尾是O(1)。迭代很容易,您也可以从O(1)中列表中的任何已知位置删除项目。我正在考虑使用一个简单的项目列表。当添加一个新项目时,我

我需要一个数据结构,它将以性能的方式支持以下操作:

  • 将项目添加到列表末尾
  • 按项目添加到列表中的顺序遍历列表(随机访问并不重要)
  • 从列表中删除项目

我应该使用什么类型的数据结构?(我将在下面发布我目前所想的答案。)

你应该使用链接列表。将项目添加到列表末尾是O(1)。迭代很容易,您也可以从O(1)中列表中的任何已知位置删除项目。

您应该使用链接列表。将项目添加到列表末尾是O(1)。迭代很容易,您也可以从O(1)中列表中的任何已知位置删除项目。

我正在考虑使用一个简单的项目列表。当添加一个新项目时,我只会将其添加到列表的末尾。要删除一个项目,我实际上不会将其从列表中删除,我只会将其标记为已删除,并在遍历项目时跳过它


我将跟踪列表中已删除项目的数量,当超过一半的项目被删除时,我将创建一个没有已删除项目的新列表。

我正在考虑使用一个简单的项目列表。当添加一个新项目时,我只会将其添加到列表的末尾。要删除一个项目,我实际上不会将其从列表中删除,我只会将其标记为已删除,并在遍历项目时跳过它


我将跟踪列表中已删除项目的数量,当超过一半的项目被删除时,我将创建一个没有已删除项目的新列表。

循环和双链接列表。它满足所有3个要求:


将项目添加到列表末尾:O(1)。通过添加到标题->上一页。它支持按添加列表的相同顺序遍历列表。您可以删除任何元素。

循环和双链接列表。它满足所有3个要求:


将项目添加到列表末尾:O(1)。通过添加到标题->上一页。它支持按添加列表的相同顺序遍历列表。你可以删除任何元素。

< p>听起来像是链表,但是有一个需要考虑的问题。当你说“从列表中删除一个项目”时,这取决于你是否有“完整的项目”要删除,或者仅仅是它的值

我将澄清:假设您的值是字符串。您可以构造一个包含一个字符串和两个链接指针(向前和向后)的类/结构。当给定这样一个类时,很容易将其从O(1)中的列表中删除。在伪代码中,删除项c如下所示(请忽略验证测试):

但是,如果您希望删除包含字符串“hello”的项,则需要O(n),因为您需要遍历列表

如果是这种情况,我建议使用链表和哈希表的组合进行O(1)查找。插入到列表末尾(伪代码):

扫描列表就是扫描链接列表,没有问题:

i = head

while i != null:
    ... do something with i.value ...
    i = i.forwards
按值从列表中删除项(伪代码,无验证测试):


这听起来像是一个链表,但是有一个需要考虑的问题。当你说“从列表中删除一个项目”时,这取决于你是否有“完整的项目”要删除,或者仅仅是它的值

我将澄清:假设您的值是字符串。您可以构造一个包含一个字符串和两个链接指针(向前和向后)的类/结构。当给定这样一个类时,很容易将其从O(1)中的列表中删除。在伪代码中,删除项c如下所示(请忽略验证测试):

但是,如果您希望删除包含字符串“hello”的项,则需要O(n),因为您需要遍历列表

如果是这种情况,我建议使用链表和哈希表的组合进行O(1)查找。插入到列表末尾(伪代码):

扫描列表就是扫描链接列表,没有问题:

i = head

while i != null:
    ... do something with i.value ...
    i = i.forwards
按值从列表中删除项(伪代码,无验证测试):

假设Java(其他语言有类似的结构,但我首先找到了JavaDocs):

  • 如果您有要删除的项的索引
  • 如果您只拥有该项目,而没有其位置
    • 假设Java(其他语言有类似的结构,但我首先找到了JavaDocs):

      • 如果您有要删除的项的索引
      • 如果您只拥有该项目,而没有其位置

      +1。如果要从中删除的“结束”是尾部,则需要用头指针和尾指针封装它,但这只是一个实现细节。对,没错。哪一端是不相关的,例如,您可以使用双链接列表,或者循环列表(如果您喜欢)。+1。如果要从中删除的“结束”是尾部,则需要用头指针和尾指针封装它,但这只是一个实现细节。对,没错。哪一端是不相关的,例如,你可以使用一个双链接列表,或者一个循环列表,如果你喜欢的话。这意味着删除时间是O(n)。实际上,这取决于预期的删除率和数组的大小——如果偶尔需要创建一个包含数百万项的新列表,可能会在应用程序中产生抖动。请参阅下面我的答案以获得建议。这意味着删除时间为O(n)。实际上,这取决于预期的删除率和数组的大小——如果偶尔需要创建一个包含数百万项的新列表,可能会在应用程序中产生抖动。请参阅下面我的答案以获得建议。
      i = head
      
      while i != null:
          ... do something with i.value ...
          i = i.forwards
      
      item_to_remove = hash.find_by_key(some_string)
      if (item_to_remove != null):
          hash.delete_key(some_string)
          item_to_remove.backwards = item_to_remove.forwards
          if item_to_remove.forwards = null: tail = item_to_remove.backwards
          if item_to_remove.backwards = null: head = item_to_remove.forwards
          delete item_to_remove