如何在C ++中遍历堆栈?

时间:2014-04-21 09:31:50

标签: c++ stack traversal

是否可以在C ++中遍历std::stack

使用以下方法遍历不适用。因为std::stack没有成员end

std::stack<int> foo;

// ..

for (__typeof(foo.begin()) it = foo.begin(); it != foo.end();  it++)
{
    // ...
}

9 个答案:

答案 0 :(得分:13)

  

是否可以在C ++中遍历std :: stack?

没有。堆栈是一种数据结构,当您有兴趣将元素放在顶部并从顶部获取元素时,您应该使用该数据结构。如果你想要一个可迭代的堆栈,要么为堆栈角色使用不同的数据结构(std::vector?),要么自己写一个。

答案 1 :(得分:5)

不可能直接遍历std:: stack,因为它没有end成员,这就是应该认为堆栈数据结构只有一个指针的方式。但是,仍然有两个懒惰的技巧可以遍历它:

1)基于循环:

while(!st.empty()) {
        cout << s.top();
        s.pop();
    }

基于循环的方法存在的问题:

  • 原始堆栈为空。

2)基于递归:

template <typename T>
void traverse_stack(stack<T> & st) {
    if(st.empty())
        return;
    T x = st.top();
    cout << x << " ";
    st.pop();
    traverse_stack(st);
    st.push(x);
}

基于递归的方法的优点:

  • 维护原始堆栈元素。

基于递归的方法存在的问题:

  • 维护内部堆栈。
  • 对于大容量堆栈可能会失败。

答案 2 :(得分:2)

认为可以遍历stack。我能想到的最好的方法是使用std::vector使用push_back(), pop_back()

来使用向量

堆栈不提供开始或结束成员函数,因此您不能将range based for loop与两者一起使用。

在您的情况下,如果您真的想要迭代它,最好选择其他数据结构。

答案 3 :(得分:2)

正如您所提到的,您需要打印以进行调试,这样的事情可能对您有用:

// Example program
#include <iostream>
#include <string>
#include <stack>
#include <vector>
#include <algorithm>

template <typename T>
void StackDebug(std::stack<T> s)
{
    std::vector<T> debugVector = std::vector<T>();
    while (!s.empty( ) )
    {
        T t = s.top( );
        debugVector.push_back(t);
        s.pop( );
    }

    // stack, read from top down, is reversed relative to its creation (from bot to top)
    std::reverse(debugVector.begin(), debugVector.end());
    for(const auto& it : debugVector)
    {
        std::cout << it << " ";
    }
}

int main()
{

    std::stack< int > numbers;
    numbers.push( 9 );
    numbers.push( 11 );

    StackDebug(numbers);
}

正如预期的那样,输出是“9 11”

答案 4 :(得分:1)

我们无法遍历堆栈。堆栈是一种容器适配器,专门设计用于在 LIFO 上下文中操作(后进先出),其中元素仅从容器的一端插入和提取。元素从&#34; back&#34;推出/弹出特定容器的名称,称为堆栈的顶部。堆栈不是为了显示这种行为,为此我们有其他容器

答案 5 :(得分:1)

如果您想实现 LIFO 概念并能够同时迭代,请使用 std::deque。 要模拟堆栈,请使用 push_front()、front()、pop_front()

https://en.cppreference.com/w/cpp/container/deque

内部 deque 是一系列“单独分配的固定大小的数组”,因此在处理大量数据时效果明显好于堆栈,但比向量差。

答案 6 :(得分:1)

可以在 STL 的 std::stack 上编写一个简单的包装器并迭代底层容器,引用自 reference

<块引用>

容器必须满足SequenceContainer的要求

此容器可通过 protected member c 访问,因此 this 之类的内容可能适用于您的情况:

#include <stack>
#include <iostream>
#include <iterator>

template <typename T, typename Container = std::deque<T>>
struct DebugStack : private std::stack<T, Container> {
    auto& push(T& elem) {
        std::stack<T>::push(elem);
        return *this;
    }
    auto& push(T&& elem) {
        std::stack<T>::push(elem);
        return *this;
    }
    auto& pop() {
        std::stack<T>::pop();
        return *this;
    }
    T top() {
        return std::stack<T>::top();
    }
    void print() {
        auto const& container = std::stack<T>::c;
        //T should be printable
        std::copy(begin(container), end(container), std::ostream_iterator<T>(std::cout, " "));
        std::cout<<'\n';
    }
};

int main() {
    {
        DebugStack<int> stack;
        stack.push(1).push(2).push(3).push(4);
        stack.print();
        stack.pop().pop().pop();
        stack.print();
    }

    {
        DebugStack<std::string> stack;
        stack.push("First").push("Second").push("Third").push("Fourth");
        stack.print();
        stack.pop().pop().pop();
        stack.print();
    }
}

输出:

1 2 3 4 
1 
First Second Third Fourth 
First 

您可以将 auto 返回类型更改为 DebugStack(如在 here 中)以使此解决方案适用于 C++11,因为 ValidationError 引入了返回类型的自动推导{3}}。

答案 7 :(得分:0)

#include <stack>

using std::stack;    

stack< int > numbers;
numbers.push( 1 );
numbers.push( 2 );

while ( not numbers.empty( ) )
{
    int number = numbers.top( );
    numbers.pop( );
}

http://en.cppreference.com/w/cpp/container/stack

答案 8 :(得分:-1)

您可以进行for循环:

for (stack<T> newStack = stack; !newStack.empty(); newStack.pop()){
   T item = newStack.top();
}