在C ++中使用向量实现堆栈

时间:2018-09-28 13:35:37

标签: c++ templates vector stack

#include<iostream>
#include<vector>
using namespace std;
class Stack {

private:
    int maxSize;
    vector<int> v;
    int top;
public:
    Stack(int size) {
        this->maxSize = size;
        this->v.reserve(this->maxSize);
        this->top = -1;
    }

    void push(int j) {
        if (!(this->isFull())) {
            this->v[++this->top] = j;
        } else {
            cout << "stack is full"<<endl;
        }

    }

    int pop() {
        if (!(this->isEmpty())) {

            return this->v[this->top--];
        } else {
            cout << "\nstack is empty"<<endl;
            cout<<  "StackOverflow "<<endl;
        }
    }

    int peak() {
        return this->v[this->top];
    }
    bool isEmpty() {
        return (this->top == -1);
    }

    bool isFull() {
        return (this->top == this->maxSize - 1);
    }

};

int main() {

    Stack s(10);

    s.push(10);
    s.push(20);
    cout<<s.pop();
    cout<<"\n"<<s.pop();
    s.push(40);
    cout<<"\n"<<s.pop();

}

由于以下原因,如何使此代码更好,更可靠:

  • 此代码的输出为20 10 40。

  • 但是在输出中,我想在每次输出后打印“堆栈为空” 从堆栈中弹出所有元素之后的时间 堆栈

  • 每次都无法打印“堆栈为空”

3 个答案:

答案 0 :(得分:3)

您的代码中包含UB:

this->v[++this->top] = j;

 return this->v[this->top--];    

等等。您在std::vector中保留空间的事实并不使访问大量元素合法,您无法访问元素。而且您使代码过于复杂-std::vector保持其大小,因此根本不需要索引top。您需要做的是push_back()添加元素,并使用back()访问最后一个元素,然后使用pop_back()删除它。您可以使用std::vector>::empty()std::vector::size()来检查是否还有元素。

答案 1 :(得分:2)

代码中的特定问题是由于您尝试使用std::vector进行越界访问;其行为是 undefined 。请注意,reserve不能使该数量的元素可供使用;只有潜在可用,而无需随后的内存重新分配。如果您使用的是at而不是[],则您的C ++标准库将抛出运行时错误。

std::vector具有push_backpop_back函数,可让您合理地有效地使用它来建模堆栈。

但是,到目前为止,typedef std::stack<int> Stack;代替所有代码是最好的方法。

请勿使用C ++标准库容器对象为C ++标准库中的其他容器建模。容器对象真的很难正确编写;并进行大量调试。

答案 2 :(得分:1)

以编程方式,仅当调用pop时堆栈已为空时才打印“堆栈为空”,而不是当堆栈中有1个元素且仅在调用pop之后为空时才打印。

假设堆栈上有1个元素。因此top为0。

int pop() {
    if (!(this->isEmpty())) {

if评估为true,因此不会打印任何内容。这是因为isEmpty()的值为false设置为0时,求值为top

您要做的是先弹出,然后然后检查堆栈是否为空。无论哪种方式,一开始都要检查它,因为您无法弹出空堆栈。