当前位置: 首页 > news >正文

C语言 之 【栈的简介、栈的实现(初始化、销毁、入栈、出栈、判空、栈的大小、访问栈顶元素、打印)】

目录

1.栈的简介

2.栈的实现

2.1实现须知

2.2头文件预览

2.2.1头文件细节

2.3 栈的初始化

2.4 栈的销毁

2.5 入栈

2.6 出栈

2.7 判空

2.8 栈的大小

2.9 访问栈顶元素

2.10 出栈的打印


1.栈的简介

栈是一种数据结构,是一种特殊的线性表,

栈只允许在一端进行插入和删除数据的操作

 进行数据插入和删除操作的一端称为栈顶,另一端称为栈底

栈中的数据元素遵守后进先出LIFO(Last In First Out)的原则。

可以把栈理解为一个垃圾桶,先丢进去的垃圾在桶底,

后丢进去的东西会覆盖在表面(即在桶顶)

只有先倒出桶顶的垃圾,才能倒出桶底的垃圾

压栈:栈的插入操作叫做进栈/压栈/入栈,入数据在栈顶

出栈:栈的删除操作叫做出栈。出数据也在栈顶 

 

2.栈的实现

2.1实现须知

前面说了,栈是是一种线性表,所以既可以用数组实现栈也可以用链表实现栈

但是,数组的缓存利用较高,所以选择用数组实现栈

显然,实践中都是按需申请空间,所以使用动态数组实现栈

2.2头文件预览

#pragma once
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
#include <stdbool.h>typedef int STDataType;
typedef struct Stack
{STDataType* a;int top;int capacity;
}ST;
//初始化
void StackInit(ST* st);
//销毁
void StackDestroy(ST* st);
//入栈
void StackPush(ST* st, STDataType val);
//出栈
void StackPop(ST* st);
//判空
bool STEmpty(ST* st);
//大小
int STSize(ST* st);
//访问栈顶元素
STDataType STTop(ST* st);

2.2.1头文件细节

(1)防止头文件内容在同一个编译单元内被多次展开

#pragma once

(2)包含必要的头文件(库函数、开空间、断言、布尔值)

(3)数据类型重命名,(以后只改这一处,就可以改变栈所存储的数据类型)

typedef int STDataType;

(4)与顺序表相同,多个数据存储在结构体中,其中

变量a,指向堆上一块用来存储数据的空间,

变量top,标明栈顶元素的位置或栈顶元素位置的下一个位置(依照具体实现而定)

变量capacity,标明栈的容量

(5)结构体typedef一下,不然名字太长了

(6)关于函数接口的设计

一:用户在函数外可以直接创建一个栈对象,然后传入它的地址,各函数用一级指针接收后,在函数内部使用指针就可以改变栈对象

二:如果用户在函数外创建的是一个栈类型的指针,初始化函数体内部就malloc一个栈对象,然后要么返回malloc后的指针,要么参数使用二级指针,以达到目的

方法一可以使各接口参数列表基本一致,所以我选择它(个人按需选择)

2.3 栈的初始化

void StackInit(ST* st)
{//传入的结构体指针一定不为空assert(st);//为栈存储数据开好空间,初始化的时候未指向有效内存,可以直接使用st->ast->a = (STDataType*)malloc(sizeof(STDataType) * 4);if (st->a == NULL){perror("malloc fail");exit(1);}st->capacity = 4;st->top = 0;     //栈顶元素的下一个位置,站的元素个数
}

 (1)结构体指针一定不为空,所以加断言

(1)最开始结构体中的变量a并未指向有效内存,可以直接用它接收返回值

(1)注意空间开辟失败的问题

top的初始值一般常取0 或1

(1)top == 0

此时 top 指向的是栈顶元素的下一个位置,因为

当第一个元素入栈时,top++,top的值就是1,正好是该元素下标的下一个位置

(2)top == -1

此时 top 指向的是栈顶元素的位置,因为

当第一个元素入栈时,top++,top的值就是0,正好是该元素的下标

2.4 栈的销毁

void StackDestroy(ST* st)
{assert(st);free(st->a);st->a = NULL;st->capacity = st->top = 0;
}

断言结构体指针,释放堆上申请的空间,还原成空对象即可

2.5 入栈

void StackPush(ST* st, STDataType val)
{assert(st);if (st->top == st->capacity){STDataType* temp = (STDataType*)realloc(st->a, sizeof(STDataType) * st->capacity * 2);if (temp == NULL){perror("realloc fail");exit(1);}st->a = temp;//谨防内存泄漏,需要使用临时变量st->capacity *= 2;}st->a[st->top] = val;st->top++;
}

(1)老生常谈,断言结构体指针

(2)入栈之前,判断一下扩容操作

1.top的值正好是栈中元素的个数,当个数等于容量时就进行扩容

2.可以进行2倍扩容,并注意使用临时变量接收返回值,防止接受失败导致内存泄漏

(3)top初始值是0,指向栈顶元素的下一个位置,那么直接在top位置插入元素

然后top++

2.6 出栈

void StackPop(ST* st)
{assert(st);assert(!STEmpty(st));st->top--;}

(1)结构体指针不为空,栈中必须有元素才能进行出栈操作

(2)堆上申请的是一段连续的空间,并不支持一段空间释放,

只要不太浪费内存,没必要重新开空间存储剩下的数据,直接top--

2.7 判空

bool STEmpty(ST* st)
{assert(st);return st->top == 0;
}

(1)判空结构体指针

(2)top的值就是栈中元素的个数

2.8 栈的大小

int STSize(ST* st)
{assert(st);return st->top;
}

(1)判空结构体指针

(2)top的值就是栈中元素的个数

2.9 访问栈顶元素

STDataType STTop(ST* st)
{assert(st);assert(!StackEmpty(st));return st->a[st->top - 1];
}

 (1)判空结构体指针

(2)top的初始值是0,是栈顶元素下标的后一个位置

2.10 栈的打印

栈并不支持遍历访问,只能访问栈顶元素即不提供遍历访问的接口

想要知道所有元素

只有边访问栈顶元素,边出栈

当然,如果需要保留元素,可提前保存一下

ST st;
StackInit(&st);
StackPush(&st, 1);
StackPush(&st, 2);
StackPush(&st, 3);
StackPush(&st, 4);
StackPush(&st, 5);
StackPush(&st, 6);while (!STEmpty(&st))
{printf("%d ", STTop(&st));StackPop(&st);
}

http://www.xdnf.cn/news/259849.html

相关文章:

  • 从数据到故事:用可视化工具讲好商业“话本“
  • 【2-sat】2-sat算法内容及真题
  • Java零基础入门Day4:数组与二维数组详解
  • 二项分布习题集 · 题目篇
  • 2024浙江省赛 J. Even or Odd Spanning Tree
  • PMP-第七章 项目成本管理(二)
  • unity webgl netbox2本地部署打开运行
  • FormCalc 支持的编程语言和软件
  • 【基础算法】二分查找的多种写法
  • 通过组策略使能长路径
  • 我的创作纪念日,5.1特别篇
  • 英一真题阅读单词笔记 20-21年
  • 第 1 篇:起点的选择:为何需要超越数组与链表?
  • 深度解析 Let‘s Encrypt 证书申请:从核心概念到实战避坑指南
  • Open3d函数 认识
  • Java实现区间合并算法详解
  • 【AI提示词】奥卡姆剃刀思维模型专家
  • 基于随机森林的糖尿病预测模型研究应用(python)
  • Qt编译报错:Unexpected compiler version, expected Clang 18.0.0 or newer——Qt安装MSVC编译器
  • 一种快速计算OTA PSRR的方法(Ⅱ)
  • 银河麒麟操作系统QT程序打包,使用 linuxdeployqt 自动打包
  • IntelliJ IDEA 保姆级使用教程
  • ALiBi (Attention with Linear Biases) 优化LLM 模型注意力
  • 每日一题洛谷P8635 [蓝桥杯 2016 省 AB] 四平方和c++
  • 抽奖算法场景
  • Cherry Studio的MCP协议集成与应用实践:从本地工具到云端服务的智能交互
  • 【2025最新】MySQL的各种锁有哪些?各种索引优化有哪些(索引覆盖,索引下推,索引跳跃扫描等)?怎么设计索引?排查索引?
  • P20:Inception v3算法实战与解析
  • ThreadLocal理解
  • Manus AI多语言手写识别技术解析