[数据结构]栈详解

目录

一、栈的概念及其结构

二、栈的实现

[1.栈的初始化 void STInit(ST* ps);](#1.栈的初始化 void STInit(ST* ps);)

[2.栈的插入 void STPush(ST* ps, STDataType x);](#2.栈的插入 void STPush(ST* ps, STDataType x);)

[3.栈的删除 void STPop(ST* ps);](#3.栈的删除 void STPop(ST* ps);)

[4.栈的大小计算 int STSize(ST* ps);](#4.栈的大小计算 int STSize(ST* ps);)

[5.判断栈是否为空 bool STEmpty(ST* ps);](#5.判断栈是否为空 bool STEmpty(ST* ps);)

[6.栈的销毁 void STDestroy(ST* ps);](#6.栈的销毁 void STDestroy(ST* ps);)

[7.访问栈顶元素 STDataType STTop(ST* ps);](#7.访问栈顶元素 STDataType STTop(ST* ps);)

三、栈的操作合集

Stack.h

stack.c

test.c


一、栈的概念及其结构

栈:一种特殊的线性表,其只允许在固定的一端进行插入和删除元素操作。 进行数据插入和删除操作的一端
称为栈顶,另一端称为栈底。 栈中的数据元素遵守后进先出 LIFO ( Last In First Out )的原则。
压栈:栈的插入操作叫做进栈 / 压栈 / 入栈, 入数据在栈顶
出栈:栈的删除操作叫做出栈。 出数据也在栈顶

二、栈的实现

栈的实现一般可以使用 数组或者链表实现 ,相对而言数组的结构实现更优一些。因为数组在尾上插入数据的代价比较小。

1.栈的初始化 void STInit(ST* ps);

复制代码
//栈的初始化
void STInit(ST* ps)
{
       assert(ps);
       ps->a = malloc(sizeof(STDataType) * 4);
       if (ps->a == NULL)
       {
              perror("malloc fail");
              return;
       }
       ps->capacity = 4;
       ps->top = 0;//代表top表示的是栈顶元素的下一个位置:刚开始top指向的是第一个元素,表示0,当第一个元素插入后top++表示1
}

2.栈的插入 void STPush(ST* ps, STDataType x);

复制代码
//栈的插入
void STPush(ST* ps, STDataType x)
{
       assert(ps);
       if (ps->top == ps->capacity)
       {
              STDataType* tmp = (STDataType*)realloc(ps->a, sizeof(STDataType) *  ps->capacity * 2);//扩容到当前的二倍
              if (tmp == NULL)
              {
                      perror("realloc fail");
                      return;
              }
                      ps->a = tmp;
                      ps->capacity *= 2;
       }
       ps->a[ps->top] = x;
       ps->top++;
}

3.栈的删除 void STPop(ST* ps);

复制代码
//栈的删除
void STPop(ST* ps)
{
       assert(ps);
       assert(!STEmpty(ps));
       ps->top--;
      
}

在栈操作函数中,栈指针 ps 是操作栈的基础,如果 ps 为 NULL,那么后续对 ps 指向的栈结构的任何访问(如 ps->top)都会导致未定义行为,通常是程序崩溃。因此,在进行栈操作之前,需要先确保 ps 不是 NULL,assert(!STEmpty(ps)); 实际上是在检查栈不为空的情况下才继续执行后续操作

4.栈的大小计算 int STSize(ST* ps);

复制代码
int STSize(ST* ps)
{
       assert(ps);
       return ps->top;
}

5.判断栈是否为空 bool STEmpty(ST* ps);

复制代码
//判断栈是否为空
bool STEmpty(ST* ps)
{
       assert(ps);
       return ps->top == 0;
}

6.栈的销毁 void STDestroy(ST* ps);

复制代码
//栈的销毁
void STDestroy(ST* ps)
{
       assert(ps);
       free(ps->a);
       ps->a = NULL;
       ps->top = 0;
       ps->capacity = 0;
}

7.访问栈顶元素 STDataType STTop(ST* ps);

复制代码
//访问栈顶元素
STDataType STTop(ST* ps)
{
       assert(ps);
       assert(!STEmpty(ps));
       return ps->a[ps->top-1];
}

三、栈的操作合集

Stack.h

复制代码
#pragma once
#include<stdio.h>
#include<assert.h>
#include<stdlib.h>
#include<stdbool.h>
#define N 10
typedef int STDataType;
typedef struct Stack
{
       int* a;
       int top;//下标
       int capacity;
}ST;
//栈的初始化
void STInit(ST* ps);
//栈的插入
void STPush(ST* ps, STDataType x);
//栈的删除
void STPop(ST* ps);
//
int STSize(ST* ps);
//判断栈是否为空
bool STEmpty(ST* ps);
//栈的销毁
void STDestroy(ST* ps);
//访问栈顶元素
STDataType STTop(ST* ps);
//不支持打印,因为不能保证后进先出

stack.c

复制代码
#include"Stack.h"
//栈的初始化
void STInit(ST* ps)
{
       assert(ps);
       ps->a = malloc(sizeof(STDataType) * 4);
       if (ps->a == NULL)
       {
              perror("malloc fail");
              return;
       }
       ps->capacity = 4;
       ps->top = 0;//代表top表示的是栈顶元素的下一个位置:刚开始top指向的是第一个元素,表示0,当第一个元素插入后top++表示1
}
//栈的插入
void STPush(ST* ps, STDataType x)
{
       assert(ps);
       if (ps->top == ps->capacity)
       {
              STDataType* tmp = (STDataType*)realloc(ps->a, sizeof(STDataType) *  ps->capacity * 2);//扩容到当前的二倍
              if (tmp == NULL)
              {
                      perror("realloc fail");
                      return;
              }
                      ps->a = tmp;
                      ps->capacity *= 2;
       }
       ps->a[ps->top] = x;
       ps->top++;
}
//栈的删除
void STPop(ST* ps)
{
       assert(ps);
       assert(!STEmpty(ps));
       ps->top--;
       /*在栈操作函数中,栈指针 ps 是操作栈的基础,如果 ps 为 NULL,
              那么后续对 ps 指向的栈结构的任何访问(如 ps->top)都会导致未定义行为,
              通常是程序崩溃。因此,在进行栈操作之前,需要先确保 ps 不是 NULL
              assert(!STEmpty(ps)); 实际上是在检查栈不为空的情况下才继续执行后续操作*/
}
//
int STSize(ST* ps)
{
       assert(ps);
       return ps->top;
}
//判断栈是否为空
bool STEmpty(ST* ps)
{
       assert(ps);
       return ps->top == 0;
}
//栈的销毁
void STDestroy(ST* ps)
{
       assert(ps);
       free(ps->a);
       ps->a = NULL;
       ps->top = 0;
       ps->capacity = 0;
}
//访问栈顶元素
STDataType STTop(ST* ps)
{
       assert(ps);
       assert(!STEmpty(ps));
       return ps->a[ps->top-1];
}

test.c

复制代码
#include"Stack.h"
int main()
{
       ST st;
       STInit(&st);
       STPush(&st, 1);
       STPush(&st, 2);
       STPush(&st, 3);
       STPush(&st, 4);
       STPush(&st, 5);
       while (!STEmpty(&st))
       {
              printf("%d ", STTop(&st));
              STPop(&st);
       }
       STDestroy(&st);
}
相关推荐
2401_841495641 分钟前
【LeetCode刷题】二叉树的直径
数据结构·python·算法·leetcode·二叉树··递归
数智工坊26 分钟前
【数据结构-树与二叉树】4.5 线索二叉树
数据结构
数智工坊1 小时前
【数据结构-树与二叉树】4.3 二叉树的存储结构
数据结构
独好紫罗兰1 小时前
对python的再认识-基于数据结构进行-a004-列表-实用事务
开发语言·数据结构·python
铉铉这波能秀1 小时前
LeetCode Hot100数据结构背景知识之列表(List)Python2026新版
数据结构·leetcode·list
历程里程碑2 小时前
Linux20 : IO
linux·c语言·开发语言·数据结构·c++·算法
DeeplyMind2 小时前
第七章:数据结构大比拼
数据结构·计算机科学·少儿编程·少儿科技读物
元亓亓亓2 小时前
考研408--数据结构--day8--遍历序列&线索二叉树
数据结构·考研·408·线索二叉树
xiaoxue..2 小时前
合并两个升序链表 与 合并k个升序链表
java·javascript·数据结构·链表·面试
驭渊的小故事3 小时前
简单模板笔记
数据结构·笔记·算法