数据结构之栈

目录

一、定义

二、构造

  1、具象形状

  2、建栈

  3、入栈

  4、出栈

  5、查看栈顶元素

  6、判断栈是否为空

  7、栈的大小

三、结尾

定义

  • 一种数据结构

  • 一种特殊的线性表

  • 遵循先进后出(First In Last Out)原则

返回目录

构造

  • 注:本文兼并STL模板与手打
  • 不想看俺BB可向下跳

 具象形状

  栈就相当是一堆垒起来或者是将要垒起来的书

数据结构之栈

  当我们只有一只手(另一只手不知道在干什么)时,我们想要稳稳的拿书,一定不可能从底下开始,或者是中间开始拿书吧?(不管你可不可以,反正我没那技术

  所以我们需要从顶部开始拿书,我们从顶部开始拿书的原因不就是想要将书垒起来吗?

  所以我们计算机也提供了给我们试试垒书和拿书的过程。

返回目录

正片开始

 建栈

  我们既然要将“书”垒起来,那我们就需要位置来给我们垒起书。

  要用栈也是同样的道理,我们需要先建栈。

  • STL版

  用C++自带的STL(标准模板库)是非常简单的。

  我们只需要引入栈对应的stack库建立即可。

#include <stack>
using namespace std;
stack< /*数据类型*/ > /*变量名*/;
// 如:
#include <stack>
using namespace std;
stack<int> S;

// 另一种写法
#include <stack>
std::stack< /*数据类型*/ > /*变量名*/;
//如:
#include <stack>
std::stack<int> S;

  • 手写版(数组写法)

  绝不会告诉你我只会数组的模拟

const int N = /*数据大小(根据题目修改)*/;
/*数据类型*/ stack[N]; // 数据存放的地点
int top = 0; // 栈顶指针
// 如:
const int N = 100001;
int S[N];
int top = 0;

返回目录

 入栈

  既然用来让我们“垒书”的地方建好了,那么我们就要开始“垒书”了。

  • STL版

  stack库给我们打包好了一个叫做 push() 的入栈函数,可以让我们将同样类型的数据丢到栈里面。

  我们上面定义的栈是int类型的,所以我们丢到栈里面的元素也应该是int类型的,如果用了不同类型的变量元素,程序会报错。

int a;
S.push(a);
  • 手写版(数组写法)

  我们要将数据放入栈里,那么栈的大小会增大,栈顶的高度会上升。

void push(int a) {
    ++top;
    S[top] = a;
}

返回目录

 出栈

  诶,书的顺序错了?

  不要紧,我们可以从头上一本一本地拿开,知道看到顺序错误的那本书。

  • STL版

  同样,stack库给我们打包好了一个叫做 pop() 的出栈函数,可以让我们将栈最上面的元素丢出来,也就是把栈顶弹出。(棒打出头鸟

  所以我们只要一句话就可以将栈顶提走,灰常高冷

S.pop();
  • 手写版(数组写法)

  我们把栈顶的元素丢出去,意味着栈的大小变小了,所以手写的出栈函数就只有一句话。

void pop() {
    --top;
}

返回目录

 查看栈顶元素

  我们可以将书从最顶端拿走,也可以查看最顶端的书。

  同样的,我们也可以查看栈顶的元素。

  • STL版

  stack库提供给我们一个叫做 top() 的函数,可以查看栈顶的元素。

int a = S.top();
printf("%d", a);

或者是

printf("%d", S.top());
  • 手写版(数组写法)

  我们一开始定义了top为栈顶指针,每次入栈时自增1(++top),每次出栈时自减1(--top),所以top保存的数字是栈顶元素在数组中的位置,所以top()函数相当于返回数组的第top个元素。

int top() {
    return S[top];
}

int main (void) {
    ...巴拉巴拉...
    printf("%d", top());
    ...巴拉巴拉...
}

返回目录

 判断栈是否为空

  在现实中我们“垒书”,有垒没垒是一目了然的,but在我们的程序里我们不一定看得出来。

  所以我们需要判断一下我们垒起来的“书”是不是空的。

  • STL版

  stack库提供给我们一个叫做 empty() 的函数,当栈是 空的 的时候,这个函数会返回一个true给我们;当栈不是 空的 的时候,函数会返回一个false给我们。

  一般来说,我们判断是否为空的返回值为bool值,为了好看,我一般会用文字的方式来测试。

if (S.empty()) {
    printf("没有东西哦~");
}
else {
    printf("有点东西哦~");
}
  • 手写版(数组写法)

  我们一开始定义了一个名为top的栈顶指针,它的初始值为0,所以我们判断栈是否为空的时候,判断top与0的关系即可。

bool empty() {
    return (top == 0); // 如果top == 0返回true,否则返回false。
}

int main(void) {
    ...巴拉巴拉...
    if (empty()) {
        printf("没有东西哦~");
    }
    else {
        printf("有点东西哦~");
    }
    ...巴拉巴拉...
}

返回目录

 栈的大小

  在现实中我们“垒书”,垒了几本书是一目了然的(吧?),but在我们的程序里我们不一定看得出来。

  所以我们需要查看一下我们垒起来的“书”有几本。

  • STL版

  stack库提供给我们一个叫做 size() 的函数,可以返回栈里面元素的个数。

printf("%d", S.size());
  • 手写版(数组写法)

  我们一开始定义了top为栈顶指针,每次入栈时自增1(++top),每次出栈时自减1(--top),所以top同时也保存了栈里面元素的数量。

int size() {
    return top;
}

返回目录

结尾

 用STL写的栈 与 用手打的栈 各有千秋,一般来说,没有吸氧(开\(O2\)优化)的话,用手打的栈比用STL写的栈来的快;吸氧(开\(O2\)优化)的话,两者时间差不多。

 而且单说打比赛的话,从CSP到NOIP,是不可以开O2优化的,所以总体上是手打栈快。

 所以我选择STL!!!!!

数据结构之栈

 因为STL打的快啊!!!!!(懒人必备神器

返回目录

上一篇:c++,stl,string容器的API,构造,赋值,访问,拼接,查找替换


下一篇:STL线程安全