【问题标题】:What is the major difference between a vector and a stack?向量和堆栈之间的主要区别是什么?
【发布时间】:2012-02-05 20:03:17
【问题描述】:

两者都像堆栈一样。两者都有推送和弹出操作。

在某些内存布局上有区别吗?

【问题讨论】:

  • 堆栈默认容器是双端队列 - class Container = deque<T>
  • @Jesse 有任何链接支持吗? vector 的默认容器是什么?
  • 这里是MSDN 的链接。您还应该得到一个包含定义的pdf copy of the C++ standard draft。 Vector是标准的stl容器之一,stack是使用一个标准容器的特化。

标签: c++ stl containers


【解决方案1】:

std::stack 相比,std::vector 具有多个可访问性和修改操作。对于std::stack,您可能只需要系统地执行操作,您可以在最后一个元素上方push()pop() 最后一个元素。

std::vector 在这个意义上更灵活,它有多个操作,您可以在其中insert()erase() 介于两者之间。

重点是,std::stack 需要提供底层容器。默认为std::deque,但也可以是std::vectorstd::list
另一方面,std::vector 保证是一个可以使用operator [] 访问的连续数组。

【讨论】:

  • 你说:The major point is that, std::stack needs to be provided the underlying container. 但这个例子没有显示提供容器的任何额外努力? cplusplus.com/reference/stl/stack/push
  • @AnishaKaul,这是因为默认template < class T, class Container = deque<T> > class stack;。因此,如果您不提供任何容器,则假定它为std::deque。有关更多信息,请参阅我在答案中发布的链接。
  • 好的,谢谢,容器可以换了!美好的。 Vector的默认容器是new创建的动态数组?
  • @AnishaKaul,不,std::vector 是一个独立的容器。它使用std::allocator,是的,它可能正在使用new[]
  • @Anisha:当人们使用“容器”这个词时,他们通常只指 stl 容器,这里有一个link 列出了它们(尽管在 C 中已经添加了其他的++11)
【解决方案2】:

我不知道所有的实现细节,但是根据this,stack 是一个容器适配器。它确保底层容器(可以是向量、列表或双端队列)作为堆栈工作,即只允许推送和弹出,而不是随机访问。

因此,向量可以作为堆栈使用,但堆栈不能作为向量使用,因为您无法在随机位置插入或获取元素。

【讨论】:

  • +1 表示 重要的一点。 STL 包含几个容器适配器,它们不符合容器的一般要求,因为......它们不是。
【解决方案3】:

stack 是一个堆栈。它只能推送和弹出。 vector 可以做其他事情,比如插入到中间。这增加了灵活性,但减少了保证。

例如,对于一个堆栈,如果您将 A 然后 B 推到后面,那么您可以保证它们将按照 B 的顺序被移除,然后 A。vector 不保证这一点。

【讨论】:

  • 对,我刚刚看到vector有一个erase函数,可以从中间擦除。 Stack 没有这样的东西。:) 所以,vector 是一个灵活的栈。
  • @Anisha:不,这是错误的假设方式。如果应该是这种情况,链接列表、简单数组、双端队列都可以称为堆栈..rt 吗?但是堆栈是为容器或数据结构定义的一组属性。如果您的实现对于为堆栈定义的属性保持正确,则可以从上述数据结构中创建一个堆栈。
  • @ArunMu 实际上,通过堆栈我指的是称为堆栈的“容器”。
  • @AnishaKaul:哦。我只是说,即使您为堆栈的 operator[] 添加一个函数 ..它也不再是堆栈 :) 根据标准:)。只是说..
  • @AnishaKaul:如果您正在考虑任何接近继承堆栈容器的地方,那么 NOOOO.... STL 容器没有虚拟析构函数。而且我认为根据 STL 实现,这将是一项艰巨的任务......正确地保留堆栈属性
【解决方案4】:

堆栈基本上是向量的一种特殊情况。从理论上讲,向量可以随心所欲地增长。您可以删除向量中任何索引处的元素。但是,在堆栈的情况下,您可以删除元素并仅在其顶部插入它们(因此是向量的一种特殊情况)。

面对许多提供堆栈实现的库,它们通常继承自向量类/结构。我不确定,但我认为 STL (C++) 可以。

【讨论】:

  • STL 是老东西了;您可能是指标准库。不,它的stack 没有定义为继承自vector;它是一个模板化适配器,默认为deque,可以选择vector
【解决方案5】:

正如cplusplus.com 建议的那样:

堆栈是一种容器适配器,专门设计用于在 LIFO 上下文(后进先出)中运行,其中元素仅从容器的一端插入和提取。

这里的关键词是only,因为元素是only从容器的一端插入和提取的。

你说向量和堆栈都像堆栈一样,但这只是部分正确。向量可以表现得像堆栈,但它们也可以表现得非常不像堆栈,通过允许您执行诸如在任何索引处插入、访问任何元素、迭代整个结构等操作。

堆栈接受一个容器(例如,一个向量),并且只允许与它进行类似堆栈的交互。这有效地保证了与容器的所有交互都将遵循 LIFO:只有容器中最近添加的元素才能被访问或删除。

如果您想要一个具有类似堆栈行为的容器,那么您应该使用堆栈,前提是它对您来说特别重要的是它的行为完全是一个堆栈。如果您想要类似堆栈的行为,但可能还想要执行诸如迭代元素或修改任意位置的元素等操作,您应该使用向量。

【讨论】:

    【解决方案6】:

    我认为主要区别在于 vector 是基于范围的容器。由于它的成员函数,如开始和结束,它可以很容易地使用。 Vector 可以通过 {} 形式轻松启动。我们可以使用现代 C++ 的新特性,例如基于范围的循环。

    vector<int> vec{ 7, 3, 1, 9, 5 };
    for ( auto &i : vec ) {
        std::cout << i << std::endl;
    }
    

    而 std::stack 是不可能的。

    【讨论】:

    • 但是选择使用std::stack的人已经知道他们不关心基于范围的迭代;相反,他们想要一个简洁的界面来按明确定义的顺序推送和弹出元素。
    猜你喜欢
    • 2012-06-14
    • 2015-08-22
    • 2015-08-06
    • 2011-03-06
    • 2013-12-23
    • 2017-04-28
    • 2011-04-14
    • 2010-09-17
    • 2021-11-30
    相关资源
    最近更新 更多