跳到主要内容
极客日志极客日志面向AI+效率的开发者社区
首页博客我的书AI学习GitHub 精选镜像AI 生图工具UI配色美学关于
搜索内容 / 工具 / 仓库 / 镜像...⌘K搜索
注册
博客列表
C算法

数据结构入门:基于数组的栈实现详解

栈这种先进后出的线性表结构,对比了数组与链表作为底层存储的优劣,最终选择数组实现。详细阐述了栈的定义、接口设计及核心功能,包括初始化、入栈、出栈、获取栈顶、判空及销毁操作。通过动态扩容机制解决空间限制问题,并提供了完整的 C 语言头文件、源文件及测试代码示例,帮助读者理解栈的基本原理与工程实践。

FrontendX发布于 2026/3/16更新于 2026/9/1067 浏览
数据结构入门:基于数组的栈实现详解

1. 栈的概念

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

  • 压栈:栈的插入操作叫做进栈(压栈、入栈),数据在栈顶。
  • 出栈:栈的删除操作叫做出栈,数据也在栈顶。

2. 栈的底层结构选择

实现栈时,可以选择顺序表或链表作为底层结构。

  • 数组实现:插入元素时在指定位置操作,删除元素时移动 top 指针。缺点是可能存在空间浪费。
  • 链表实现:按需申请和释放空间,无空间浪费。但每次插入或删除都需要遍历链表,时间复杂度为 O(N)。

综合来看,采用数组结构实现栈更为合适,解决了动态扩容问题后效率更高。

3. 栈的实现

3.1 栈的定义

typedef int SDataType;

typedef struct Stack {
    SDataType* a;      // 栈底指针
    int capacity;      // 栈的容量大小
    int top;           // 栈实际存储数据的个数
} Stack;

3.2 栈的接口

// 初始化栈
void StackInit(Stack* ps);
// 栈顶入数据
void StackPush(Stack* ps, SDataType x);
// 获取栈顶元素
SDataType StackTop(Stack* ps);
// 删除栈顶数据
void StackPop(Stack* ps);
// 栈是否为空
bool StackEmpty(Stack* ps);
// 栈的大小
int StackSize(Stack* ps);
// 销毁栈
void StackDestroy(Stack* ps);
3.2.1 初始化栈
void StackInit(Stack* ps) {
    assert(ps);
    ps->a = NULL;
    ps->capacity = ps->top = 0;
}
3.2.2 栈顶入数据
void StackPush(Stack* ps, SDataType x) {
    assert(ps);
    // 增容
    if (ps->capacity == ps->top) {
        int newcapacity = ps->capacity == 0 ? 4 : ps->capacity * 2;
        SDataType* tmp = (SDataType*)realloc(ps->a, sizeof(SDataType) * newcapacity);
        if (tmp == NULL) {
            printf("StackPush(): realloc fail\n");
            exit(-1);
        }
        ps->a = tmp;
        ps->capacity = newcapacity;
    }
    ps->a[ps->top] = x;
    ps->top++;
}

首先判断栈空间是否足够,不够则扩容。空间足够直接在 top 位置插入数据并更新计数。初始容量为 0 时设置为 4,否则翻倍。

3.2.3 栈是否为空
bool StackEmpty(Stack* ps) {
    assert(ps);
    return ps->top == 0;
}

top 记录栈中数据元素的个数,top 为 0 表示栈为空。

3.2.4 获取栈顶元素
SDataType StackTop(Stack* ps) {
    assert(ps);
    assert(!StackEmpty(ps));
    return ps->a[ps->top - 1];
}

保证栈不为空,直接返回数组最后一个元素。

3.2.5 删除栈顶元素
void StackPop(Stack* ps) {
    assert(ps);
    assert(!StackEmpty(ps));
    ps->top--;
}

栈不为空才能删除数据,直接减小 top 即可。

3.2.6 栈的大小
int StackSize(Stack* ps) {
    assert(ps);
    return ps->top;
}

直接返回 top 值。

3.2.7 销毁栈
void StackDestroy(Stack* ps) {
    assert(ps);
    free(ps->a);
    ps->a = NULL;
    ps->capacity = ps->top = 0;
}

释放动态申请的数组空间,并将成员变量重置。

4. 完整代码实现

Stack.h

#pragma once
#include <stdio.h>
#include <stdbool.h>
#include <stdlib.h>
#include <assert.h>

typedef int SDataType;

typedef struct Stack {
    SDataType* a;
    int capacity;
    int top;
} Stack;

void StackInit(Stack* ps);
void StackPush(Stack* ps, SDataType x);
SDataType StackTop(Stack* ps);
void StackPop(Stack* ps);
bool StackEmpty(Stack* ps);
int StackSize(Stack* ps);
void StackDestroy(Stack* ps);

Stack.c

#define _CRT_SECURE_NO_WARNINGS
#include "Stack.h"

void StackInit(Stack* ps) {
    assert(ps);
    ps->a = NULL;
    ps->capacity = ps->top = 0;
}

void StackPush(Stack* ps, SDataType x) {
    assert(ps);
    if (ps->capacity == ps->top) {
        int newcapacity = ps->capacity == 0 ? 4 : ps->capacity * 2;
        SDataType* tmp = (SDataType*)realloc(ps->a, sizeof(SDataType) * newcapacity);
        if (tmp == NULL) {
            printf("StackPush(): realloc fail\n");
            exit(-1);
        }
        ps->a = tmp;
        ps->capacity = newcapacity;
    }
    ps->a[ps->top] = x;
    ps->top++;
}

SDataType StackTop(Stack* ps) {
    assert(ps);
    assert(!StackEmpty(ps));
    return ps->a[ps->top - 1];
}

void StackPop(Stack* ps) {
    assert(ps);
    assert(!StackEmpty(ps));
    ps->top--;
}

bool StackEmpty(Stack* ps) {
    assert(ps);
    return ps->top == 0;
}

int StackSize(Stack* ps) {
    assert(ps);
    return ps->top;
}

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

test.c

#define _CRT_SECURE_NO_WARNINGS
#include "Stack.h"

void TestStack1() {
    Stack st;
    StackInit(&st);
    StackPush(&st, 1);
    StackPush(&st, 2);
    StackPush(&st, 3);
    StackPush(&st, 4);
    StackPush(&st, 5);
    
    SDataType ret = StackTop(&st);
    printf("%d ", ret);
    
    StackPop(&st);
    StackPop(&st);
    
    int size = StackSize(&st);
    printf("%d ", size);
    
    StackDestroy(&st);
}

int main() {
    TestStack1();
    return 0;
}

目录

  1. 1. 栈的概念
  2. 2. 栈的底层结构选择
  3. 3. 栈的实现
  4. 3.1 栈的定义
  5. 3.2 栈的接口
  6. 3.2.1 初始化栈
  7. 3.2.2 栈顶入数据
  8. 3.2.3 栈是否为空
  9. 3.2.4 获取栈顶元素
  10. 3.2.5 删除栈顶元素
  11. 3.2.6 栈的大小
  12. 3.2.7 销毁栈
  13. 4. 完整代码实现
  14. Stack.h
  15. Stack.c
  16. test.c

更多推荐文章

查看全部
  • GDB 调试与 Core Dump 段错误排查指南(Linux/C/C++)
  • Web 可访问性最佳实践:构建人人可用的前端界面
  • MySQL 临时表:特性、生命周期与使用示例
  • 分布式任务调度:多数据库兼容的策略封装
  • Virt-A-Mate 虚拟实境软件功能介绍
  • Linux System V 共享内存:原理、实操与避坑指南
  • UMI 机器人数据采集通用框架
  • LightRAG:轻量级 RAG 模型构建知识库问答系统
  • C++ 多态核心原理与实现
  • AM32 固件实战:STM32 无刷电机控制优化指南
  • 基于 Java SpringBoot 的企业设备信息一体化管理系统
  • AI 时代的技术民主化:为什么文科生可能成为最大受益者?
  • C++ STL 竞赛常用容器详解
  • Text Generation Web UI:本地 AI 模型部署与管理工具
  • Hive 0.7.1 基于 Ubuntu 的伪分布式环境搭建与配置
  • 飞算 JavaAI 工具箱:项目文档生成与代码规范优化实践
  • RAG 优化方案与实践详解
  • Agent 操控手机与电脑屏幕的技术解析与应用指南
  • UE5.3 C++ ARPG 游戏开发:创建角色类
  • HTML 基础语法与常用标签详解

相关免费在线工具

  • 加密/解密文本

    使用加密算法(如AES、TripleDES、Rabbit或RC4)加密和解密文本明文。 在线工具,加密/解密文本在线工具,online

  • Gemini 图片去水印

    基于开源反向 Alpha 混合算法去除 Gemini/Nano Banana 图片水印,支持批量处理与下载。 在线工具,Gemini 图片去水印在线工具,online

  • Base64 字符串编码/解码

    将字符串编码和解码为其 Base64 格式表示形式即可。 在线工具,Base64 字符串编码/解码在线工具,online

  • Base64 文件转换器

    将字符串、文件或图像转换为其 Base64 表示形式。 在线工具,Base64 文件转换器在线工具,online

  • Markdown转HTML

    将 Markdown(GFM)转为 HTML 片段,浏览器内 marked 解析;与 HTML转Markdown 互为补充。 在线工具,Markdown转HTML在线工具,online

  • HTML转Markdown

    将 HTML 片段转为 GitHub Flavored Markdown,支持标题、列表、链接、代码块与表格等;浏览器内处理,可链接预填。 在线工具,HTML转Markdown在线工具,online