手把手教你使用C语言实现堆栈数据结构算法-两种方式(链表+数组)

news/2024/10/4 1:16:57

堆栈

定义

栈(stack) 是一种遵循先入后出逻辑的线性数据结构,常见操作入栈,出栈,访问栈


图片来源:https://www.hello-algo.com/

栈的实现

栈遵循先入后出的原则,因此我们只能在栈顶添加或删除元素。然而,数组和链表都可以在任意位置添加和删除元素,因此栈可以视为一种受限制的数组或链表。换句话说,我们可以“屏蔽”数组或链表的部分无关操作,使其对外表现的逻辑符合栈的特性。

基于链表的实现

使用链表实现栈时,我们只需将链表的头节点视为栈顶,尾节点视为栈底

入栈操作,只需将元素插入链表头部(这种节点插入方式被称为“头插法”),出栈操作,只需将头结点从链表中删除即可。

/* 基于链表实现的栈 */
typedef struct
{ListNode *top; // 将头节点作为栈顶int size;      // 栈的长度
} LinkedListStack;/* 构造函数 */
LinkedListStack *newLinkedListStack()
{LinkedListStack *s = malloc(sizeof(LinkedListStack));s->top = NULL;s->size = 0;return s;
}/* 析构函数 */ 
void delLinkedListStack(LinkedListStack *s)
{while (s->top){ListNode *n = s->top->next;free(s->top);s->top = n;}free(s);
}/* 获取栈的长度 */
int size(LinkedListStack *s)
{return s->size;
}/* 判断栈是否为空 */
bool isEmpty(LinkedListStack *s)
{return size(s) == 0;
}/* 入栈 */
void push(LinkedListStack *s, int num)
{ListNode *node = (ListNode *)malloc(sizeof(ListNode));node->next = s->top; // 更新新加节点指针域node->val = num;     // 更新新加节点数据域s->top = node;       // 更新栈顶s->size++;           // 更新栈大小
}/* 访问栈顶元素 */
int peek(LinkedListStack *s)
{if (s->size == 0){printf("栈为空\n");return INT_MAX;}return s->top->val;
}/* 出栈 */
int pop(LinkedListStack *s)
{int val = peek(s);ListNode *tmp = s->top;s->top = s->top->next;// 释放内存free(tmp);s->size--;return val;
}

基于数组的实现

使用数组实现栈时,可以将数组的尾部作为栈顶,入栈,出栈分别在尾部添加与删除元素,时间复杂度为O(1);

由于入栈元素可能会源源不断的增加,使用动态数组操作可避免后续增容操作

/* 基于数组实现的栈 */
typedef struct
{int *data;int size;
} ArrayStack;/* 构造函数 */
ArrayStack *newArrayStack()
{ArrayStack *stack = malloc(sizeof(ArrayStack));// 初始化一个大容量,避免扩容stack->data = malloc(sizeof(int) * MAX_SIZE);stack->size = 0;return stack;
}/* 析构函数 */
void delArrayStack(ArrayStack *stack)
{free(stack->data);free(stack);
}/* 获取栈的长度 */
int size(ArrayStack *stack)
{return stack->size;
}/* 判断栈是否为空 */
bool isEmpty(ArrayStack *stack)
{return stack->size == 0;
}/* 入栈 */
void push(ArrayStack *stack, int num)
{if (stack->size == MAX_SIZE){printf("栈已满\n");return;}stack->data[stack->size] = num;stack->size++;
}/* 访问栈顶元素 */
int peek(ArrayStack *stack)
{if (stack->size == 0){printf("栈为空\n");return INT_MAX;}return stack->data[stack->size - 1];
}/* 出栈 */
int pop(ArrayStack *stack)
{int val = peek(stack);stack->size--;return val;
}
/* 测试代码 */
int main()
{ArrayStack *stack = newArrayStack();push(stack, 1);push(stack, 2);push(stack, 3);printf("%d\n", pop(stack));printf("%d\n", pop(stack));printf("%d\n", pop(stack));printf("%d\n", pop(stack));delArrayStack(stack);return 0;
}

典型应用

  • 浏览器的后退与前进,软件中的撤销和反撤销
  • 程序内存管理
  • 深度优先算法,回溯算法
  • 后缀表达式取值

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.ryyt.cn/news/55135.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈,一经查实,立即删除!

相关文章

全国大学高校专业数据 API 接口

全国大学高校专业数据 API 接口 提供大学专业基础数据,持续更新,各类专业属性。1. 产品功能2023 年数据已更新; 提供最新的全国高校专业基本信息; 总计近 3000 条专业精准基础数据; 每月一次数据更新校正; 同时包含了专业开设课程列表; 全接口支持 HTTPS(TLS v1.0 / v1…

网页可读内容抽取 API 数据接口

网页可读内容抽取 API 数据接口 智能提取文章关键元素信息,智能抽取,多种元素信息。1. 产品功能智能提取网页可阅读内容; 提供网页可阅读内容的 HTML 代码; 支持传递网页 HTML 或网页 URL 参数; 支持多种元素信息抽取,包括文章标题、作者、文字方向、语言、内容、内容(不…

9 张图总结 MySQL 架构

原文:9 张图总结一下 MySQL 架构前言 目前大部分的后端开发人员对MySQL的理解可能停留在一个黑盒子阶段。 对MySQL基本使用没什么问题,比如建库、建表、建索引,执行各种增删改查。 所有很多后端开发人员眼中的MySQL如下图所示:导致在实际工作中碰到MySQL中死锁异常、SQL性能…

The 1st Universal Cup. Stage 8: Slovenia

Preface 这场其实是昨天打的,但因为今天没训练就摆烂拖到今天才补题和写博客 这场题感觉都挺可做的,但前期出题有点慢导致后期没时间了,徐神和祁神赛后 20min 过了 J 有点可惜A. Bandits 题都没看,不做评价B. Combination Locks 不难发现这题本质就是在 0/1 串上操作,每次…

梁山县技工学校继续教育刷课脚本-JavaScript编写

脚本 学习网站:lsx.qzjystudy.com 脚本地址:梁山县技工学校继续教育-刷课脚本 教程 1.插件安装(以Microsoft Edge浏览器为例)打开最中间那个蓝色绿色的浏览器,谷歌之类的浏览器也可以点击屏幕右上角三个点,图示位置,然后点击扩展点击获取扩展搜索Tampermonkey,并点击获取…

学习公社刷课脚本-JavaScript编写

脚本 学习网站:教育干部网络学院: www.enaea.edu.cn 脚本地址:教育干部网络学院-刷课脚本 教程 1.插件安装(以Microsoft Edge浏览器为例)打开最中间那个蓝色绿色的浏览器,谷歌之类的浏览器也可以点击屏幕右上角三个点,图示位置,然后点击扩展点击获取扩展搜索Tampermonke…

【SQL注入】代码安全审计经验分享

一、MyBatis框架中的注入漏洞 Mybatis框架支持的CURD功能可以直接搜索XML文件中的${和${}拼接的SQL语句,如果SQL的参数可控,就可能造成注入风险。 另外,有的SQL语句使用的是注解开发,把SQL语句可以直接写在了代理接口方法上方,审计的时候可以将两种情况都注意一下,或许有…

2024-08-31:用go语言,给定一个数组apple,包含n个元素,每个元素表示一个包裹中的苹果数量; 另一个数组capacity包含m个元素,表示m个不同箱子的容量。 有n个包裹,每个包裹内装有

2024-08-31:用go语言,给定一个数组apple,包含n个元素,每个元素表示一个包裹中的苹果数量; 另一个数组capacity包含m个元素,表示m个不同箱子的容量。 有n个包裹,每个包裹内装有指定数量的苹果,以及m个箱子,每个箱子的容量不同。 任务是将这n个包裹中的所有苹果重新分配…