数据结构复习之栈-顺序栈的实现

172 阅读2分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第5天,点击查看活动详情

栈(Stack)是一种访问受限的线性表,是一种只允许在一端进行插入或删除的线性表,它是一种先进后出(FILO)的数据结构。

在栈不为空时,我们只能看到栈顶元素。

image.png

操作

  • 推入(压栈,push):把元素放入堆栈顶端,堆栈顶端移到新放入的元素
  • 弹出(弹栈,pop):将堆栈顶端元素移除,堆栈顶端移动到移除后的下一个元素
  • 获取栈顶元素

栈的入栈出栈操作.gif

基本特点

  • 先入后出,后入先出
  • 除头尾节点之外,每个元素有一个前驱,一个后继

栈的实现

栈====>线性表

  • 顺序栈:顺序实现
  • 链栈:链式实现
  • 共享栈(对顶栈):两个栈共享同一片内存空间

image.png

#include <stdio.h>
#include <stdlib.h>

// 定义栈结构
typedef struct stack {
    int *data; // 存储数据的区域:可以动态扩容
    int cap, size; // cap: 容量上限  size:栈中有多少个元素
} stack;

// 生成栈: 栈->数据区 先建立栈的结构,在建立存储数据的那个结构(数据源)
// n: 容量上限
stack *init_stack(int n) {
    stack *s = (stack *)malloc(sizeof(stack)); // 开辟一个栈这么大的空间,把首地址存起来
    s->data = (int *) malloc(sizeof(int) * n); // 数据区的大小:新申请的一片空间
    s->size = 0;
    s->cap = n;
    return s;
}
// 销毁栈(与创建顺序相反):数据区->栈的顺序反向进行销毁
void delete_stack(stack *s) {
    free(s->data);
    free(s);
}
// 入栈:顺序栈空间是有限的,需要判断有没有存满
// 存满 ----> 进行扩容操作
int push (stack *s, int val) {
    if (s->cap == s->size) {
        // 存满:扩容
        s->cap *= 2; // 容量扩为原来的2倍
        s->data = (int *) realloc(s->data, sizeof(int) * s->cap); // 数据区重迁移 s->data: 想扩容的地址
    }
    s->data[s->size] = val;
    s->size++;
    return 0;
}
// 出栈
int pop(stack *s) {
    if (s->size == 0) {
        return -1; // 无元素,不需要出栈
    }
    s->size--;
    return 0;
}
// 获取栈顶元素
int top(stack *s) {
    if (s->size == 0) {
        return -1;
    }
    return s->data[s->size - 1];
}
// 打印栈当中的所有元素
void show_stack(stack *s) {
    printf("cap: %d, size: %d\n", s->cap, s->size);
    for (int i = 0; i < s->size; i++) {
        printf("%d", s->data[i]);
    }
    printf("\n----------------\n");
}
int main() {
    int n, m; // n: 操作次数  m:容量上限
    scanf("%d%d", &n, &m);
    stack *s = init_stack(m);
    printf("s->cap: %d, s->size: %d\n", s->cap, s->size);
    // 0: 入栈  1:出栈  其他:获取栈顶元素
    for (int i = 0; i < n; i++) {
        int a;
        scanf("%d", &a);
        if (a == 0) {
            scanf("%d", &a);
            push(s, a);
        } else if (a == 1) {
            pop(s);
        } else {
            printf("top -> %d\n", top(s));
        }
        show_stack(s);
    }
    delete_stack(s);
    s = NULL;
    return 0;
}