• 顺序栈及其(C++)实现

    现在来研究一个 IntStack 类,它存储了一个静态的整数栈并将执行刚才讨论过的栈操作。该类具有的成员变量如表 1 所示。

    表 1 栈类的成员变量
    成员变量 描 述
    stackArray 指向整数数组的 unique_ptr 独占指针。当构造函数执行时,它使用 stackArray 动态分配数组的存储
    capacity 一个保存栈的大小的整数。这是栈最多可以保存的元素的个数,而不是当前栈中元素的最大值
    Top 用来标记栈顶的整数。它指定将被添加到栈的下一个项目的位置

    该类的成员函数如表 2 所示:

    表 2 栈类的成员函数
    成员函数 描 述
    构造函数 该类的构造函数将接受一个整数参数,该参数指定了栈的大小。这个大小的整数数组被动态分配存储并赋值给 stackArray。另外,变量 top 被初始化为 0,表示栈当前为空
    push push 函数接受一个整数参数,该参数将被压入栈顶
    pop pop 函数使用一个整数引用形参。栈顶部的值被删除并复制到引用形参中
    isEmpty 如果栈为空则返回 true,否则返回 false。top 设置为 0 时则栈为空

    注意,即使构造函数会动态地为栈数组分配存储,但是它仍然被视为一个顺序栈,因为一旦分配完毕,该栈的大小就不能改变。

    该类的代码显示如下:

    //IntStack.h 的内容
    #include <memory>
    using namespace std;
    class IntStack
    {
        unique_ptr<int[]>stackArray;
        int capacity;
        int top;
      public:
        // Constructor
        IntStack(int capacity);
        // Member functions
        void push(int value);
        void pop (int &value);
        bool isEmpty() const;
        // Stack Exceptions
        class Overflow {};
        class Underflow {};
    };

    除了表 2 中描述的栈成员之外,IntStack 类还定义了两个名为 Overflow 和 Underflow 的内部类,用作栈异常。

    如果在代码执行过程中,遇到了代码无法按既定任务执行的情况,则称该代码段出现异常。在顺序栈的情况下,如果栈中没有更多的空间,则在调用 push 压栈的过程中就会发生溢出异常。同样,如果在调用 pop 出栈时栈内却没有任何内容可以返回,则会发生下溢异常。

    代码在检测到异常发生之后,会立即通知程序的其余部分,方法是创建描述异常的值并使用 throw 语句将该值传递给程序的其余部分。

    例如,push 函数可通过执行以下语句来通知发生溢出异常:

    throw InstStack::Overflow();

    而 pop 函数则可以执行以下语句:

    throw IntStack::Underflow();

    该语句通知程序发生了下溢异常。默认情况下,当程序的任何部分抛出异常时,程序将终止并显示错误消息。这个默认行为可以通过一个被称为捕获异常的进程来改变。

    IntStack 构造函数可分配一个指定容量的数组,并将成员变量 top 设置为 0。所有的栈函数都使用 top,使它始终指向栈数组中的下一个可用槽。当 top 等于 capacity 时,没有更多的槽用于存储值,下一次 push 的调用就会拋出异常。

    同样,当 top 为零时,栈就是空的,对 pop 的调用会抛出一个异常。因为在程序中没有任何规定来捕捉这两个异常,所以它们中的任何一个都会以错误信息终止程序。注意,在向栈中添加一个值之后,push 会递增 top 的值;而在返回存储在 stackArray[top] 中的值之前,pop 会递减 top 的值。

    //IntStack.cpp 的内容
    #include "intstack.h"
    IntStack::IntStack(int capacity)
    {
        stackArray = make_unique<int[]>(capacity);
        this->capacity = capacity;
        top = 0;
    }
    void IntStack::push(int value)
    {
        if (top == capacity)
            throw IntStack::Overflow();
        stackArray[top] = value;
        top++;
    }
    bool IntStack::isEmpty() const
    {
        return top == 0;
    }
    void IntStack::pop(int &value)
    {
        if (isEmpty()) throw IntStack::Underflow();
        top--;
        value = stackArray[top];
    }

    下面的程序演示了栈类及其成员函数的使用。请注意,在出栈的时候,其顺序刚好和值入栈的顺序相反。

    // This program illustrates the IntStack class.
    #include "intstack.h"
    #include <iostream>
    using namespace std;
    int main()
    {
        IntStack stack(5);
        int values[] = { 5, 10, 15, 20, 25 };
        int value;
        cout << "Pushing. . . \n";
        for (int k = 0; k < 5; k++)
        {
            cout << values[k] << " ";
            stack.push(values[k]);
        }
        cout << "\nPopping. . .\n";
        while (!stack.isEmpty())
        {
            stack.pop(value);
            cout << value << " ";
        }
        cout << endl;
        return 0;
    }

    程序输出结果:

    Pushing. . .
    5 10 15 20 25
    Popping. . .
    25 20 15 10 5

    在此程序中,使用参数 5 调用构造函数,这将如图 1 所示设置成员变量。由于 top 被设置为 0,所以该栈是空的。


    使用构造函数和参数 5 创建的栈
    图 1 使用构造函数和参数 5 创建的栈

更多...

加载中...