数据结构与算法《栈》

概念:
      栈(stack)又名堆栈,它是一种运算受限的线性表。其限制是仅允许在表的一端进行插入和删除运算。这一端被称为栈顶,相对地,把另一端称为栈底。向一个栈插入新元素又称作进栈、入栈或压栈,它是把新元素放到栈顶元素的上面,使之成为新的栈顶元素;从一个栈删除元素又称作出栈或退栈,它是把栈顶元素删除掉,使其相邻的元素成为新的栈顶元素,栈也称为后进先出表

特点:
     1. 栈具有记忆作用,对栈的插入与删除操作中,不需要改变栈底指针;
     2. 限定性数据结构;
     3. 栈可以用来在函数调用的时候存储断点,做递归时要用到栈。

种类:
     栈可以用两种方式来实现,一种方法是用数组实现栈,这种栈成为静态栈;另外一种方法是用链表实现栈,这种栈叫做动态栈

运算:
     1. 设置一个空栈;
     2. 插入一个新的栈顶元素;
     3. 删除栈顶元素;
     4. 读取栈顶元素;
     5. 凡是对数据处理具有“后进先出”的特点,都可以用栈来操作。

存储结构(顺序栈、链栈):
     1.顺序栈:用一组连续的存储单元存放从栈底到栈顶的数据元素,一般用一维数组表示,设置一个简单变量top指示栈顶位置,称为栈顶指针,它始终指向待插入元素的位置。

     栈的上溢:
          栈满时(top = stacksize),还有元素要进栈。
     栈的下益:
          栈空时(top = 0),还有元素要出栈。
     2.链栈:用指针实现的栈叫链栈,栈的容量事先不能估计时采用的数据结构。

静态栈实现(C++):
stackLz.hxx文件

#ifndef STACKLZ_HXX
#define STACKLZ_HXX

#include <stdexcept>

template <class T, int MAXSIZE> class StackLz { // MAXSIZE由用户创建对象时自行设置
    public:
        StackLz();          // 构造函数
        unsigned int stackLength() const;   // 当前栈元素总数
        void push(T const &);       // 进栈, const &修饰是为了防止用户自定义的类型T过于庞大, 减小形参开销
        void pop();         // 出栈
        T top() const;          // 返回栈顶元素
        bool isEmpty() const;       // 返回栈是否为空, const修饰是为了该方法不改变数据成员的值
        bool isFull() const;        // 返回栈是否已满
    private:
        T elems[MAXSIZE];       // 包含元素的数组
        unsigned int numElems;      // 元素的当前总个数
};

template <class T, int MAXSIZE> 
unsigned StackLz<T, MAXSIZE>::stackLength() const {
    return numElems;
}

template <class T, int MAXSIZE> 
StackLz<T, MAXSIZE>::StackLz():numElems(0) {    // 初始时栈为空
    // do nothing
}

template <class T, int MAXSIZE>
void StackLz<T, MAXSIZE>::push(T const &elem) {
    if(numElems == MAXSIZE) {
        throw std::out_of_range("StackLz<>::push(): stack is full");    // 栈上溢
    }
    elems[numElems] = elem;   // 附加元素
    ++numElems;               // 增加元素的个数
}

template<class T, int MAXSIZE>
void StackLz<T, MAXSIZE>::pop() {
    if (numElems <= 0) {
        throw std::out_of_range("Stack<>::pop(): empty stack");     // 栈下溢
    }
    --numElems; // 减少元素的个数
}

template <class T, int MAXSIZE>
T StackLz<T, MAXSIZE>::top() const {
    if (numElems <= 0) {
        throw std::out_of_range("Stack<>::top(): empty stack");
    }
    return elems[numElems-1];   // 返回最后一个元素
}

template <class T, int MAXSIZE>
bool StackLz<T, MAXSIZE>::isEmpty() const {
    return numElems == 0;
}

template <class T, int MAXSIZE>
bool StackLz<T, MAXSIZE>::isFull() const {
    return numElems == MAXSIZE;
}

#endif

main.cpp文件

#include <iostream>
#include <string>
#include <cstdlib>
#include "stackLz.hxx"

using namespace std;

int main(int argc, char **argv)
{
    try {
        StackLz<int, 20>  int20Stack;       // 可以存储20个int元素的栈
        StackLz<int, 40>  int40Stack;       // 可以存储40个int元素的栈
        StackLz<string, 40> string40Stack;  // 可存储40个string元素的栈

        // 使用可存储20个int元素的栈
        int20Stack.push(7);
        cout << int20Stack.top() << endl;   // 输出7
        int20Stack.pop();

        // 使用可存储40个string的栈
        string40Stack.push("hello");
        cout << string40Stack.top() << endl;    // 输出hello
        string40Stack.pop();    
        string40Stack.pop();    // Exception: Stack<>::pop<>: empty stack

        return 0;
    }
    catch (exception const &ex) {
        cerr << "Exception: " << ex.what() << endl;
        return EXIT_FAILURE;    // 退出程序且有ERROR标记
    }
}

PS:使用非类型类模板自定义栈,且所有算法的时间复杂度都为O(1)。

栈的应用:
     1. 子程序的嵌套调用;
     2. 函数的递归实现;
     3. 后缀表达式求值;
     4. 中缀表达式转换成后缀表达式;
     5. 二叉树非递归遍历;
     6. 不胜枚举…=_=

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值