[数据结构]栈详解

目录

一、栈的概念及其结构

二、栈的实现

[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);
}
相关推荐
by2099913 小时前
哈希表——快速找到数据:冲突、删除与扩容的实现
数据结构·c++·哈希算法·散列表
Code_Solitude13 小时前
c语言:关于qsoet函数知识点
c语言·数据结构·算法
Pniubi14 小时前
快速排序(力扣基础)(递归)
java·数据结构·算法
inrichtt1 天前
第八课时:SPI总线揭秘:四线全双工通信的奥
c语言·数据结构·stm32·单片机·嵌入式硬件
HPtiger1 天前
数据结构——选择排序
数据结构·算法·排序算法
丑梨数据1 天前
信创环境里跑文档工具:格式兼容与本地合规的几个坑
数据结构·人工智能·算法·决策树·排序算法
烂蜻蜓1 天前
Pandas入门教程(四):Series数据结构——创建、索引与常用方法
数据结构·pandas
CS创新实验室1 天前
一棵树怎么做到“自平衡还不太费力“?——红黑树的旋转与染色
数据结构·算法·红黑树·408·计算机考研
Logic1011 天前
C语言/数据结构位运算题解:异或XOR找出被挑选一次的果子编号——只出现一次的数字
c语言·数据结构·算法·数组·位运算·时间复杂度·空间复杂度
从小白到软工1 天前
4-3 项目-学生成绩管理系统(上)
c语言·开发语言·数据结构·经验分享·ai编程