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

【数据结构】栈的深入解析--用C语言实现

文章目录

  • 1.栈的概念
  • 2.栈的底层结构
  • 3.栈的功能
  • 4.栈的实现
    • 4.1.栈结构的定义
    • 4.2.栈的初始化
    • 4.3.栈的销毁
    • 4.4.入栈
    • 4.5.出栈
    • 4.6.取栈顶元素
    • 4.7.获取栈中有效元素个数
  • 5.完整代码
    • Stack.h
    • Stack.c
    • main.c
    • 运行结果

1.栈的概念

是一种特殊的线性表,只允许数据在固定的一段进行插入、删除元素的操作

  • 我们把进行插入或删除元素的一端成为栈顶,另一端成为栈底
  • 栈中的元素遵循先进后出原则
  • 入栈:在栈顶插入元素,又称压栈/进栈
  • 出栈:删除栈顶元素
    请添加图片描述

2.栈的底层结构

思考:栈是一种线性表,只在一端进行插入或删除操作,因此我们可以选择用数组(顺序表)或链表来作为它的底层结构,那么用哪个更优呢?

时间复杂度分析:
数组:相当于在末尾添加或删除元素
入栈:O(1) 出栈:O(1)
链表:把表头当作栈顶,相当于头插或头删,需要从头节点遍历到尾节点
入栈:O(1) 出栈:O(1)
综上,时间复杂度相等

空间复杂度分析:
数组:每次扩容需要开辟相应倍数数据类型大小的空间(每次扩容乘2)
链表:每添加一个元素需要开辟相应节点大小的空间
综上,显然数组的空间复杂度更低

因此,我们通常选择数组来作为栈的底层结构

3.栈的功能

主要功能有:入栈、出栈、取栈顶元素、返回栈中有效元素个数

4.栈的实现

4.1.栈结构的定义

定义一个栈的结构体,其中的成员变量包含:数组(指针)、有效元素个数、数组容量

//栈的结构
typedef int STDataType;//栈中存储的变量类型
typedef struct Stack{STDataType* a;//变长数组,存储数据int top;//记录有效元素个数int capacity;//数组容量
}ST;

4.2.栈的初始化

创建一个空数组

void STInit(ST* ps)
{ps->a = NULL;ps->capacity = ps->top = 0;
}

4.3.栈的销毁

释放栈中数组空间,把成员变量都置为空

void STDestroy(ST* ps)
{assert(ps);if(ps->a) free(ps->a);ps->a = NULL;ps->top = ps->capacity = 0;
}

4.4.入栈

在栈顶,即数组末尾插入元素

void STPush(ST* ps, STDataType x)
{assert(ps);//判断空间是否足够-扩容if(ps->top == ps->capacity){int newCapacity = ps->capacity == 0 ? 4 : 2*ps->capacity;STDataType* tmp = (STDataType*)realloc(ps->a, newCapacity * sizeof(STDataType));//扩容失败if(tmp == NULL){perror("Realloc Failed!\n");exit(1);}ps->a = tmp;ps->capacity = newCapacity;}//空间足够ps->a[ps->top++] = x;
}

4.5.出栈

在栈顶,即数组末尾删除元素
需要先判断栈是否为空,写一个判空函数:

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

出栈的实现:

void STPop(ST* ps)
{assert(!STEmpty(ps));ps->top--;
}

4.6.取栈顶元素

返回数组中top-1位置的元素值即可

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

4.7.获取栈中有效元素个数

返回top值即可

int STSize(ST* ps)
{assert(!STEmpty(ps));return ps->top;
}

5.完整代码

Stack.h

//
//  Stack.h
#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 STInit(ST* ps);
//销毁
void STDestroy(ST* ps);//入栈
void STPush(ST* ps, STDataType x);//判空
bool STEmpty(ST* ps);//出栈
void STPop(ST* ps);//取栈顶元素
STDataType STTop(ST* ps);//有效元素个数
int STSize(ST* ps);

Stack.c

//
//  Stack.c
#include "Stack.h"void STInit(ST* ps)
{ps->a = NULL;ps->capacity = ps->top = 0;
}
void STDestroy(ST* ps)
{assert(ps);if(ps->a) free(ps->a);ps->a = NULL;ps->top = ps->capacity = 0;
}void STPush(ST* ps, STDataType x)
{assert(ps);//判断空间是否足够-扩容if(ps->top == ps->capacity){int newCapacity = ps->capacity == 0 ? 4 : 2*ps->capacity;STDataType* tmp = (STDataType*)realloc(ps->a, newCapacity * sizeof(STDataType));//扩容失败if(tmp == NULL){perror("Realloc Failed!\n");exit(1);}ps->a = tmp;ps->capacity = newCapacity;}//空间足够ps->a[ps->top++] = x;
}bool STEmpty(ST* ps)
{assert(ps);return ps->top == 0;
}void STPop(ST* ps)
{assert(!STEmpty(ps));ps->top--;
}STDataType STTop(ST* ps)
{assert(!STEmpty(ps));return ps->a[ps->top-1];
}int STSize(ST* ps)
{assert(!STEmpty(ps));return ps->top;
}

main.c

//main.c
#include "Stack.h"void test(void)
{ST st;STInit(&st);STPush(&st, 1);STPush(&st, 2);STPush(&st, 3);STPush(&st, 4);printf("st size: %d\n", STSize(&st));while(!STEmpty(&st)){STDataType top = STTop(&st);STPop(&st);printf("%d ", top);}printf("\n");STDestroy(&st);
}
int main(void)
{test();return 0;
}

运行结果

请添加图片描述

http://www.dtcms.com/a/286251.html

相关文章:

  • Linux 环境下 NNG 通讯库:在嵌入式设备上应用
  • [2025CVPR-目标检测方向] CorrBEV:多视图3D物体检测
  • Docker 与 GPU 训练
  • 排序【各种题型+对应LeetCode习题练习】
  • 线程控制:互斥与同步
  • IDEA高效开发:Database Navigator插件安装与核心使用指南
  • Python趣味算法:抓交通肇事犯(车牌号谜题解析)
  • nginx定制http头信息
  • 腾讯云云服务器深度介绍
  • 面试150 克隆图
  • 通缩期的 “反脆弱” 研发:新启航逆势投入 30% 营收突破 3D 白光干涉测量技术
  • 深孔加工的方法及检测方法探究 —— 激光频率梳 3D 轮廓检测
  • 29、鸿蒙Harmony Next开发:深浅色适配和应用主题换肤
  • 计算机网络基础:从协议到通信全解析(大致框架)
  • 基于 WinForm 与虹软实现人脸识别功能:从理论到实践
  • VisualXML全新升级 | 新增BusLoad计算
  • python控制linux命令反馈
  • 二刷 黑马点评 附近商户
  • 如何更改 SQLserver 数据库存储的位置 想从C盘换到D盘
  • Delphi EDI 需求分析与对接指南
  • Springboot3整合Elasticsearch8(elasticsearch-java)
  • 智和信通赋能:北京某高校校园网交换机全维度智能管控
  • 洛谷 P10112 [GESP202312 八级] 奖品分配-普及/提高-
  • 基于SpringBoot 投票系统 【源码+LW+PPT+部署】
  • Gemini Function Calling 和 Qwen3 Embedding和ReRanker模型
  • 40.限流规则
  • 用线性代数推导码分多址(CDMA)
  • 第16章 基于AB实验的增长实践——验证想法:AB实验实践
  • 【Python】一些PEP提案(三):with 语句、yield from、虚拟环境
  • 智象科技赋能金融、证券行业 IT 运维