在C#堆栈中是否有随机访问?

时间:2014-03-09 10:48:19

标签: c# stack random-access

我有点学习数据结构,所以请原谅新手问题。问题是,我在C#中使用Stack类,我想随机访问元素。我知道我可以使用ElementAt随机访问:

Stack<int> mystack = new Stack<int>(4);
...//assume the stack is filled here
int value = mystack.ElementAt(2) // if I wanted element 2

但我只能获得价值,我无法修改它。我的意思是,在List中,我可以将随机元素修改为:

List<int> mylist = new List<int>(4);
mylist[2] = 35;

我想对Stack做同样的事情,但它没有索引器。也许这是不可能的,如果是这样,我也想知道原因。我知道当需要随机访问时,通常不会使用堆栈,但在解决问题时我仍然需要它。我最终找到了一个更好的方法,但我仍然想知道。 最后,关于ElementAt(),它是O(1)或O(N)??

1 个答案:

答案 0 :(得分:6)

  

我想对Stack做同样的事情,但它没有索引器。也许这是不可能的,如果是的话,我也想知道原因。

不,这是不可能的。 Stack<T>不提供允许随机访问的任何成员(直接指向基础列表数据)。同样,Stack<T>的公共接口只能确保可以修改堆栈的顶部,而不是任何其他项目 - 这反过来意味着不必以适合自己的方式实现类随机访问(例如内部数组),但可以以随机访问不是非常高效的方式实现(例如链表)。因此,Stack<T>故意仅实现ICollection<T> interface,而IList<T>不提供随机访问的任何成员,而List<T>实际上是一个随机随机的集合访问。

最可能的原因是,正如你所说:

  

当需要随机访问时,通常不会使用堆栈

至于你的具体情况:

  

但在解决问题时我仍然需要它

在这种情况下,您显然不需要堆栈(LIFO列表),因此只需使用ElementAt

  

最后,关于ElementAt(),它是O(1)或O(N)??

与前面提到的Stack<T>类型相关,并且没有检查enumerator的实现,我会假设ElementAt使用堆栈提供的IEnumerable<T>并迭代堆栈中的元素,直到达到指定的索引,因此在这种情况下,它的行为为O(N)。

请注意,在一般情况下,这不一定是真的; ElementAt很有可能以首先检查传递给它的IList<T>是否也实现indexer defined for that interface的方式实现,在这种情况下它可以使用{{3}},在这种情况下可能会达到O(1)的复杂性。