【问题标题】:Data structure in C# that allows Reverse in O(1)C# 中的数据结构,允许 O(1) 中的 Reverse
【发布时间】:2020-02-21 08:24:02
【问题描述】:

我有一些我想遍历的列表,有时从头到尾,有时从头到尾。这个列表永远不会被修改,我会多次遍历它。当我想从头到尾迭代时,我想避免在 O(n) 中反转列表的操作。

是否有一些数据结构允许这样做?

我认为 C# 中的(双重)LinkedList 实现允许这种行为很简单(通过保持列表开头的内部引用),但我不认为它是这样实现的大大地。如果我错了,你能提供一个链接吗?

【问题讨论】:

  • 您可以使用数组向前和向后迭代。
  • 就此而言,您可以向前和向后迭代任何内容,只要它具有完整的键控索引器和 Count 字段。
  • 显然没有涵盖所有可能性,但reverse foreach 问题中有大量列表/数组示例...
  • 你能告诉你在找到这样一个结构时遇到了什么麻烦吗?比如Array、List等为什么不适合?
  • 大多数时候,您可以简单地保留一个布尔值curOrder,然后在迭代时使用它来选择a[i]a[n-i-1]。在更复杂的情况下(例如,反转多个子段),有时可以使用陷阱。

标签: c# list data-structures reverse


【解决方案1】:

任何具有直接索引访问和长度(数组、列表、字符串、文件流)的数据结构都允许在 O(1) 时间内完成“反向”的表示(注意它本身就是反向的,显然迭代所有项目仍然是 O (n)。

Possible to iterate backwards through a foreach? 中有几个示例,其中“yield return”suggested by Jon Skeet 是最灵活的方式(可能性能略低于 for):

public static IEnumerable<T> FastReverse<T>(this IList<T> items)
{
    for (int i = items.Count-1; i >= 0; i--)
    {
        yield return items[i];
    }
}

作为Patrick Roberts commented,您还可以使用其他看起来像数组的数据结构 - 即具有顺序 int 键和已知高/低边界的字典可以工作(这大致是 JavaScript 数组的工作方式)。

确实,双链表(C# 中的LinkedList)是只需要正向和反向迭代时选择的数据结构......但是转换数组/列表(已经给你 O(1) 的方式来表示反向迭代)是不值得的。根据其他要求,完全切换到链表可能是一种选择。

请注意,从理论的角度来看,如果您无论如何都需要遍历所有元素,那么在反向上花费 O(n) 不会改变整体复杂性。

【讨论】:

  • 谢谢!这比我想象的要简单。
猜你喜欢
  • 2012-11-17
  • 2018-03-27
  • 2019-01-14
  • 2012-05-13
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-04-24
  • 2011-03-29
相关资源
最近更新 更多