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

C语言链式栈详解(从零开始掌握栈的链式存储实现)

在学习C语言链式栈之前,我们先来理解一下什么是“栈”。栈是一种后进先出(LIFO, Last In First Out)的数据结构,就像一摞盘子,你只能从最上面拿或放。而链式栈就是用链表的方式来实现栈的结构,相比顺序栈(数组实现),它具有动态内存分配、无需预设容量等优点。

本文将手把手教你如何用C语言实现一个完整的链式栈,包括初始化、入栈、出栈、判空、获取栈顶元素和销毁等操作。即使你是编程小白,也能轻松看懂!

为什么选择链式栈?

使用数组实现的栈(顺序栈)需要预先分配固定大小的内存,容易造成空间浪费或溢出。而链式栈通过指针动态连接节点,内存按需分配,更加灵活高效,是学习数据结构C语言实现的重要基础。

C语言链式栈详解(从零开始掌握栈的链式存储实现) C语言链式栈 链式栈实现 数据结构C语言 栈的链式存储 第1张

链式栈的基本结构

链式栈由一个个节点组成,每个节点包含两部分:

  • data:存储数据
  • next:指向下一个节点的指针

栈顶指针(通常命名为 top)始终指向当前栈顶元素。入栈时在头部插入新节点,出栈时删除头部节点。

完整代码实现

下面是一个完整的C语言链式栈实现示例,包含所有基本操作:

#include <stdio.h>#include <stdlib.h>// 定义栈节点结构typedef struct StackNode {    int data;                // 数据域    struct StackNode* next;  // 指针域} StackNode;// 定义栈类型(指向栈顶的指针)typedef StackNode* LinkStack;// 初始化栈void InitStack(LinkStack* S) {    *S = NULL;  // 栈顶置空}// 判断栈是否为空int IsEmpty(LinkStack S) {    return S == NULL;}// 入栈操作void Push(LinkStack* S, int x) {    StackNode* newNode = (StackNode*)malloc(sizeof(StackNode));    if (!newNode) {        printf("内存分配失败!\n");        return;    }    newNode->data = x;    newNode->next = *S;  // 新节点指向原栈顶    *S = newNode;       // 更新栈顶指针}// 出栈操作int Pop(LinkStack* S) {    if (IsEmpty(*S)) {        printf("栈为空,无法出栈!\n");        return -1;  // 返回错误值    }    StackNode* temp = *S;    int value = temp->data;    *S = (*S)->next;  // 栈顶下移    free(temp);       // 释放内存    return value;}// 获取栈顶元素(不出栈)int GetTop(LinkStack S) {    if (IsEmpty(S)) {        printf("栈为空!\n");        return -1;    }    return S->data;}// 销毁整个栈void DestroyStack(LinkStack* S) {    while (*S != NULL) {        StackNode* temp = *S;        *S = (*S)->next;        free(temp);    }}// 主函数测试int main() {    LinkStack stack;    InitStack(&stack);    Push(&stack, 10);    Push(&stack, 20);    Push(&stack, 30);    printf("栈顶元素:%d\n", GetTop(stack));  // 输出 30    printf("出栈:%d\n", Pop(&stack));      // 输出 30    printf("出栈:%d\n", Pop(&stack));      // 输出 20    DestroyStack(&stack);    printf("栈已销毁。\n");    return 0;}  

代码解析

  • InitStack:将栈顶指针设为 NULL,表示空栈。
  • Push:创建新节点,将其插入到链表头部,并更新栈顶。
  • Pop:删除栈顶节点,返回其值,并释放内存。
  • DestroyStack:循环释放所有节点,防止内存泄漏。

常见问题与注意事项

1. 内存管理:每次 malloc 后必须有对应的 free,否则会造成内存泄漏。

2. 空栈判断:在执行 PopGetTop 前务必检查栈是否为空。

3. 指针传递:由于要修改栈顶指针本身,函数参数需使用二级指针(如 LinkStack*)。

总结

通过本教程,你已经掌握了C语言链式栈的核心实现方法。链式栈作为栈的链式存储方式,在实际开发中非常实用,尤其适合不确定数据量的场景。建议你动手敲一遍代码,加深理解。

如果你正在学习数据结构C语言相关内容,链式栈是必经之路。掌握它,你离成为C语言高手又近了一步!