如何在C ++中实现动态可调整大小的堆栈?

时间:2014-01-17 04:25:34

标签: c++ stack

我的代码现在只是一个包含push,pop和display方法的简单堆栈。如何更改堆栈以便根据输入的元素数量动态调整堆栈大小?因此,例如,如果堆栈已满,我创建一个两倍于原始大小的新堆栈,并将数据复制到新堆栈。

感谢。

#include <iostream>
#include <stdexcept>

using namespace std;

class Stack
{
private:
    int *p;
    int top,length;

public:
    Stack(int = 0);
    ~Stack();

    void push(int);
    int pop();
    void display();
};

Stack::Stack(int size)
{
    top=-1;
    length=size;
    while(length <= 0)                //If the stack size is zero, allow user to mention it at runtime
    {
        cout<<"Stack of zero size"<<endl;
        cout<<"Enter a size for stack : ";
        cin >> length;
    }
    p=new int[length];
}

Stack::~Stack()
{
    delete [] p;
}

void Stack::push(int elem)
{
    if(top==(length-1))     //If the top reaches to the maximum stack size
    {
        throw overflow_error("Can't push onto a full stack");
    }
    else
    {
        top++;
        p[top]=elem;
    }
}
int Stack::pop()
{
    if(top==-1)
    {
       throw underflow_error("Can't pop from an empty stack");
    }
    int ret=p[top];
    top--;
    length--;

    return ret;
}

void Stack::display()
{
    for(int i = 0; i <= top; i++)
        cout<<p[i]<<" ";
    cout<<endl;
}

int main()
{
    int len;

    cout<<"Enter a size for stack : ";
    cin >> len;
    Stack s1(len);
    try{
        s1.push(1);
        s1.display();
        s1.push(2);
        s1.push(3);
        s1.push(4);
        s1.push(5);
        s1.display();
        s1.pop();
        s1.display();
        s1.pop();
        s1.display();
        s1.pop();
        s1.display();
        s1.pop();
        s1.display();
        s1.pop();
        s1.display();
    }
    catch(overflow_error){
        cerr<< "Illegal operation. Cannot push onto a full stack.";
        return -1;
    }
    catch(underflow_error){
        cerr<< "Illegal operation. Cannot pop from an empty stack.";
        return -1;
    }


}

4 个答案:

答案 0 :(得分:2)

void Stack::push(int elem)
{
    if(top==(length-1))     //If the top reaches to the maximum stack size
    {
        int* newp = new int[length * 2];
        std::memcpy(newp, p, sizeof(int) * length);
        delete[] p;
        p = newp;
        top++;
        p[top]=elem;
        length*=2;
   }
   else
   {
       top++;
       p[top]=elem;
   }

}

答案 1 :(得分:1)

标准库(std::stack)中的堆栈类通过委托给std::vector等容器类来解决这个问题。但这有点作弊。

然而,std::vector<>背后的想法相当简单且可重用。当您达到最大尺寸时,请按顺序执行以下操作:

  1. 分配新内存。如果失败(没有数据丢失)没有大问题
  2. 复制所有现有元素。使用std::uninitialized_copy而不是std::copy
  3. 交换新旧指针
  4. 删除旧对象
  5. 免费旧分配

答案 2 :(得分:0)

您可以使用new分配更多内存,并将内容复制到该内存并释放先前分配的内存(内存交换),而不是抛出异常overflow_error(“无法推送到完整堆栈”)。

void Stack::push(int elem)
{
   if(top==(length-1))     //If the top reaches to the maximum stack size
   {
    //throw overflow_error("Can't push onto a full stack");
      int *pTemp = new int[length + 10/*value u want to increment*/];
      memcpy(p,pTemp,length);  //for using this include stdlib
      delete[] p;
      p = pTemp;
   }
   top++;
   p[top]=elem;
}

答案 3 :(得分:0)

一种简单的方法是每次推送一个新元素会使堆栈溢出时将堆栈大小加倍。在那个例子中,你检测到潜在的溢出,然后你将使用声明一个新的int数组,它是旧的数组的两倍,然后将旧数组复制到这个新数组并重新指定该新数组并删除旧数组阵列。这是其他更优化的方式,但这是一种简单的方法,你可以消耗比添加新项目所需的更多的内存,但它比重新分配每个会溢出堆栈的新项目快得多。