重生之“我打数据结构,真的假的?”--3.栈和队列(无习题)
栈和队列
C语言中的栈和队列总结
在C语言中,**栈(Stack)和队列(Queue)**是两种非常重要的数据结构。它们广泛用于各种应用中,比如内存管理、任务调度、表达式求值等。本文将对这两种数据结构进行详细的介绍,并展示如何在C语言中实现它们。
1. 栈(Stack)
栈是一种先进后出(LIFO,Last In First Out)数据结构,类似于一摞盘子,最后放上去的盘子最先被拿下来。
1.1 栈的特点
- 先进后出(LIFO):最后入栈的元素最先出栈。
- 单端操作:栈的插入和删除操作都发生在栈顶。
1.2 栈的基本操作
- 压栈(Push):将元素压入栈顶。
- 弹栈(Pop):从栈顶移除元素。
- 查看栈顶元素(Peek/Top):获取栈顶元素但不删除它。
- 判断栈是否为空(isEmpty)。
1.3 栈的实现方式
栈可以通过数组或链表来实现。以下分别讨论栈的数组实现和链表实现。
1.3.1 使用数组实现栈
以下是用C语言实现栈的数组版:
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>#define MAX_SIZE 100typedef struct Stack {int items[MAX_SIZE];int top;
} Stack;// 初始化栈
void initStack(Stack* stack) {stack->top = -1;
}// 判断栈是否为空
bool isEmpty(Stack* stack) {return stack->top == -1;
}// 判断栈是否已满
bool isFull(Stack* stack) {return stack->top == MAX_SIZE - 1;
}// 压栈操作
void push(Stack* stack, int value) {if (isFull(stack)) {printf("栈已满,无法压入元素。\n");return;}stack->items[++stack->top] = value;printf("压入元素:%d\n", value);
}// 弹栈操作
int pop(Stack* stack) {if (isEmpty(stack)) {printf("栈为空,无法弹出元素。\n");return -1;}return stack->items[stack->top--];
}// 查看栈顶元素
int peek(Stack* stack) {if (isEmpty(stack)) {printf("栈为空,没有栈顶元素。\n");return -1;}return stack->items[stack->top];
}// 遍历栈
void traverseStack(Stack* stack) {if (isEmpty(stack)) {printf("栈为空。\n");return;}for (int i = 0; i <= stack->top; i++) {printf("%d ", stack->items[i]);}printf("\n");
}int main() {Stack stack;initStack(&stack);push(&stack, 10);push(&stack, 20);push(&stack, 30);printf("栈的内容:");traverseStack(&stack);printf("弹出元素:%d\n", pop(&stack));printf("栈顶元素:%d\n", peek(&stack));printf("栈的内容:");traverseStack(&stack);return 0;
}
1.3.2 使用链表实现栈
以下是使用链表实现栈的C语言代码:
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>typedef struct Node {int data;struct Node* next;
} Node;typedef struct Stack {Node* top;
} Stack;// 初始化栈
void initStack(Stack* stack) {stack->top = NULL;
}// 判断栈是否为空
bool isEmpty(Stack* stack) {return stack->top == NULL;
}// 压栈操作
void push(Stack* stack, int value) {Node* newNode = (Node*)malloc(sizeof(Node));newNode->data = value;newNode->next = stack->top;stack->top = newNode;printf("压入元素:%d\n", value);
}// 弹栈操作
int pop(Stack* stack) {if (isEmpty(stack)) {printf("栈为空,无法弹出元素。\n");return -1;}Node* temp = stack->top;int poppedValue = temp->data;stack->top = stack->top->next;free(temp);return poppedValue;
}// 查看栈顶元素
int peek(Stack* stack) {if (isEmpty(stack)) {printf("栈为空,没有栈顶元素。\n");return -1;}return stack->top->data;
}// 遍历栈
void traverseStack(Stack* stack) {Node* current = stack->top;if (isEmpty(stack)) {printf("栈为空。\n");return;}while (current != NULL) {printf("%d ", current->data);current = current->next;}printf("\n");
}int main() {Stack stack;initStack(&stack);push(&stack, 10);push(&stack, 20);push(&stack, 30);printf("栈的内容:");traverseStack(&stack);printf("弹出元素:%d\n", pop(&stack));printf("栈顶元素:%d\n", peek(&stack));printf("栈的内容:");traverseStack(&stack);return 0;
}
1.4 栈的应用
- 函数调用栈:计算机系统使用栈来保存函数调用的返回地址。
- 表达式求值和括号匹配:在表达式求值中,栈用于临时保存操作数和操作符。
- 深度优先搜索(DFS):在图的遍历中,栈可以用于实现深度优先搜索。
2. 队列(Queue)
队列是一种先进先出(FIFO,First In First Out)数据结构,类似于排队买票,第一个到达的人先买票。
2.1 队列的特点
- 先进先出(FIFO):第一个入队的元素第一个出队。
- 双端操作:插入操作发生在队尾,而删除操作发生在队头。
2.2 队列的基本操作
- 入队(Enqueue):在队尾添加一个元素。
- 出队(Dequeue):从队头移除一个元素。
- 查看队头元素(Front)。
- 判断队列是否为空(isEmpty)。
2.3 队列的实现方式
队列可以通过数组或链表来实现。以下分别介绍这两种实现方式。
2.3.1 使用数组实现队列
以下是使用数组实现队列的C语言代码:
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>#define MAX_SIZE 100typedef struct Queue {int items[MAX_SIZE];int front;int rear;
} Queue;// 初始化队列
void initQueue(Queue* queue) {queue->front = -1;queue->rear = -1;
}// 判断队列是否为空
bool isEmpty(Queue* queue) {return queue->front == -1;
}// 判断队列是否已满
bool isFull(Queue* queue) {return queue->rear == MAX_SIZE - 1;
}// 入队操作
void enqueue(Queue* queue, int value) {if (isFull(queue)) {printf("队列已满,无法入队元素。\n");return;}if (isEmpty(queue)) {queue->front = 0;}queue->items[++queue->rear] = value;printf("入队元素:%d\n", value);
}// 出队操作
int dequeue(Queue* queue) {if (isEmpty(queue)) {printf("队列为空,无法出队元素。\n");return -1;}int value = queue->items[queue->front];if (queue->front >= queue->rear) {// 队列为空queue->front = queue->rear = -1;} else {queue->front++;}return value;
}// 查看队头元素
int front(Queue* queue) {if (isEmpty(queue)) {printf("队列为空,没有队头元素。\n");return -1;}return queue->items[queue->front];
}// 遍历队列
void traverseQueue(Queue* queue) {if (isEmpty(queue)) {printf("队列为空。\n");return;}for (int i = queue->front; i <= queue->rear; i++) {printf("%d ", queue->items[i]);}printf("\n");
}int main() {Queue queue;initQueue(&queue);enqueue(&queue, 10);enqueue(&queue, 20);enqueue(&queue, 30);printf("队列的内容:");traverseQueue(&queue);printf("出队元素:%d\n", dequeue(&queue));printf("队头元素:%d\n", front(&queue));printf("队列的内容:");traverseQueue(&queue);return 0;
}
2.3.2 使用链表实现队列
以下是使用链表实现队列的C语言代码:
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>typedef struct Node {int data;struct Node* next;
} Node;typedef struct Queue {Node* front;Node* rear;
} Queue;// 初始化队列
void initQueue(Queue* queue) {queue->front = NULL;queue->rear = NULL;
}// 判断队列是否为空
bool isEmpty(Queue* queue) {return queue->front == NULL;
}// 入队操作
void enqueue(Queue* queue, int value) {Node* newNode = (Node*)malloc(sizeof(Node));newNode->data = value;newNode->next = NULL;if (isEmpty(queue)) {queue->front = queue->rear = newNode;} else {queue->rear->next = newNode;queue->rear = newNode;}printf("入队元素:%d\n", value);
}// 出队操作
int dequeue(Queue* queue) {if (isEmpty(queue)) {printf("队列为空,无法出队元素。\n");return -1;}Node* temp = queue->front;int value = temp->data;queue->front = queue->front->next;if (queue->front == NULL) {queue->rear = NULL;}free(temp);return value;
}// 查看队头元素
int front(Queue* queue) {if (isEmpty(queue)) {printf("队列为空,没有队头元素。\n");return -1;}return queue->front->data;
}// 遍历队列
void traverseQueue(Queue* queue) {Node* current = queue->front;if (isEmpty(queue)) {printf("队列为空。\n");return;}while (current != NULL) {printf("%d ", current->data);current = current->next;}printf("\n");
}int main() {Queue queue;initQueue(&queue);enqueue(&queue, 10);enqueue(&queue, 20);enqueue(&queue, 30);printf("队列的内容:");traverseQueue(&queue);printf("出队元素:%d\n", dequeue(&queue));printf("队头元素:%d\n", front(&queue));printf("队列的内容:");traverseQueue(&queue);return 0;
}
2.4 队列的应用
- 操作系统中的任务调度:队列用于实现任务调度和处理。
- 广度优先搜索(BFS):在图的遍历中,队列用于实现广度优先搜索。
- 缓存(Buffer):队列可用于实现环形缓冲区或缓冲机制。
3. 栈和队列的对比
特性 | 栈(Stack) | 队列(Queue) |
---|---|---|
数据结构类型 | 线性 | 线性 |
操作模式 | LIFO(后进先出) | FIFO(先进先出) |
插入/删除位置 | 只在一端操作(栈顶) | 两端操作(队头和队尾) |
应用场景 | 函数调用、递归、括号匹配 | 任务调度、广度优先搜索 |
4. 小结
栈和队列都是重要的线性数据结构,栈采用LIFO原则,而队列采用FIFO原则。栈和队列的操作非常简单,但它们在实际应用中起到了至关重要的作用。在C语言中,栈和队列可以通过数组或链表来实现,每种实现方式都有其优缺点。
在理解了这些数据结构的基本操作后,可以更好地应用它们来解决实际问题,如表达式求值、任务调度、图遍历等。掌握这些基础数据结构也为进一步学习更加复杂的数据结构(如树、图等)打下了坚实的基础。
相关文章:
重生之“我打数据结构,真的假的?”--3.栈和队列(无习题)
栈和队列 C语言中的栈和队列总结 在C语言中,**栈(Stack)和队列(Queue)**是两种非常重要的数据结构。它们广泛用于各种应用中,比如内存管理、任务调度、表达式求值等。本文将对这两种数据结构进行详细的介…...
《Python游戏编程入门》注-第2章2
《Python游戏编程入门》的“2.2.5 绘制线条”中提到了通过pygame库绘制线条的方法。 1 相关函数介绍 通过pygame.draw模块中的line()函数来绘制线条,该函数的格式如下所示。 line(surface, color, start_pos, end_pos, width1) -> Rect 其中,第一…...
PoissonRecon学习笔记
1. Screened Poisson Reconstruction (SPR) 源码:https://github.com/mkazhdan/PoissonRecon However, as noted by several researchers, it suffers from a tendency to over-smooth the data. 泊松重建存在过度平滑的现象。 方法:position and gradi…...
腾讯云DBA面试(一面)
摘要:腾讯云前端时间约了个了维护工程师的面试,总结下面试题。 1、oracle索引原理和mysql索引原理的区别,性能差异?b tree 和 b+ tree 区别。 (1) B+树改进了B树, 让非叶子结点只作索引使用, 去掉了其中指向data record的指针, 使得每个结点中能够存放更多的key, 因此能有更…...
Python:背景知识及环境安装
一、计算机的基础概念 1.1 什么是计算机? 最早我们有计算器,但是他只能完成算数运算的功能 而计算机能完成的工作有: (1)算术运算 (2)逻辑判断 (3)数据存储 (…...
力扣第420周赛 中等 3324. 出现在屏幕上的字符串序列
文章目录 题目介绍题解 题目介绍 题解 因为是要求按键次数最少,所以不用考虑 ‘z’ 变为 ‘a’ 的情况。 代码如下: class Solution {public List<String> stringSequence(String target) {List<String> ans new ArrayList<>();St…...
ant design vue树选择器实现部分层级禁用(指定层级或依据字段判断)
1、依据字段判断是否禁用 const handData (array, level?) > {array.forEach((item) > {if (level 0) {//获取一级菜单item.title item.levelName;item.value item.code;if (item.type LAYER) {item.disabled true;} else if (item.type JOB) {item.disabled f…...
安灯系统助力汽车零部件工厂快速解决生产异常
在汽车零部件制造领域,高效的生产管理和快速解决异常情况是确保产品质量和生产进度的关键。而安灯系统的应用,正为汽车零部件工厂带来了全新的变革,助力其快速解决生产异常。 汽车零部件工厂的生产报工产线看板直观地反映出生产的各项关键数据…...
vue父子传参的方式——Prop
Prop 每一个组件都有一个props的属性,用来接收外部传递的数据 这里我拿一个分页组件为例: 一、基础语法 1、父组件传递数据 父组件在向子组件传递数据时,基础语法如下: <template><div><common-page :pagina…...
Apache Commons Text 指南:比 String 更强大的文本处理工具
Apache Commons Text 指南:比 String 更强大的文本处理工具 在 Java 开发中,String 类是处理文本的基础工具,但当面对复杂的文本处理需求时,其局限性就显而易见了。Apache Commons Text 提供了一个更加灵活强大的文本处理工具集&…...
C++面向对象编程学习
C面向对象编程学习 前言一、C面向对象编程二、知识点学习1. 定义一个类1.1 使用struct定义1.2 使用class定义1.3 struct和class的区别 2. 类的定义方式2.1 单文件定义(Inline Definition)2.2 分离定义(Separate Definition)2.3 头…...
云轴科技ZStack亮相迪拜GITEX大会,与阿里云再次携手深化海外合作
10月14至18日,全球顶尖科技盛会GITEX GLOBAL 2024在迪拜拉开帷幕,云轴科技ZStack携全系云计算解决方案与全新AIOS智塔平台参展,向全球观众展示智算时代下的新一代智算化算力平台。 GITEX GLOBAL 2024是当今世界上最具前瞻性兼包容性的大型科技…...
SQL Server 当前日期及其未来三天的日期
当前日期及其未来三天的日期,并分别以 YYYY-MM-DD 和 yyyyMMdd 的格式展示 1、当前日期及其未来三天的日期,以 YYYY-MM-DD的格式展示 WITH CurrentDate AS (SELECT GETDATE() AS 当前日期 ) -- 使用 CONVERT 函数 SELECTCONVERT(VARCHAR(10), 当前日期,…...
QUIC(Quick UDP Internet Connections)与 RTMP(Real Time Messaging Protocol)
QUIC(Quick UDP Internet Connections)和 RTMP(Real Time Messaging Protocol)是两种不同的网络传输协议,它们在一些方面有不同的特点和应用场景。 QUIC 协议 特点 基于 UDP:QUIC 建立在 UDP 之上ÿ…...
双十一送你一份购物攻略,绿联NAS DXP2800评测
一年一度双十一,今年双十一来得特别早,所以最近已经看到不少人在讨论双十一买了啥,NAS的讨论度也挺高的。正好,是我比较懂的领域。作为一位资深的数码爱好者,同时也是绿联DH2600DXP2800双持用户,可以说我是…...
基于vue框架的的高校设备信息管理系统的设计与实现tx6d7(程序+源码+数据库+调试部署+开发环境)系统界面在最后面。
系统程序文件列表 项目功能:设备管理员,设备维护员,设备类别,设备,设备入库,设备分发,设备调拨,定期维护,维护任务,设备运行记录 开题报告内容 基于Vue框架的高校设备信息管理系统的设计与实现开题报告 一、项目背景及意义 随着高校教育事业的蓬勃发展ÿ…...
springboot3.x使用@NacosValue无法获取配置信息问题解决
一、问题描述 springboot从2.x升级到3.x后,nacos的依赖包需要改成Spring Cloud的依赖包才能继续使用。升级好以后,首先,确定我的项目是能够连上nacos并且加载到配置信息的,因为数据库等信息都是从nacos加载过来,能够正…...
sql获取时间差
MySQL SELECT TIMESTAMPDIFF(HOUR, 2023-10-01 12:00:00, 2023-10-02 15:30:00) AS hours_difference; PostgreSQL //EXTRACT(EPOCH FROM (2023-10-02 15:30:00::timestamp - 2023-10-01 12:00:00::timestamp)) // 获取的是两个时间相差的秒数,在此基础上除3600获…...
【深入理解Python中的闭包】如何有效使用嵌套函数和状态捕获!
深入理解Python中的闭包:如何有效使用嵌套函数和状态捕获 Python 作为一种动态的编程语言,允许我们用多种方式来设计和构建功能,其中之一就是 闭包(Closure)。闭包是一种强大的特性,可以帮助我们捕获和保持…...
npm配置阿里镜像库教程
为了配置npm使用阿里镜像库,可以按照以下步骤进行操作。这些步骤将帮助你加快包的下载速度,特别是在中国地区,因为阿里镜像库通常比官方npm仓库响应更快。 1. 配置全局镜像 可以通过运行以下命令来将npm的全局镜像配置为阿里镜像࿱…...
Apache JMeter压力测试工具使用
JMeter是Apache组织开发的基于Java的压力测试工具,用于对软件做压力测试。 01 软件下载 下载地址: https://jmeter.apache.org/download_jmeter.cgi 最新版本5.6.2 用浏览器下载发现慢得很,用迅雷下载非常快哟。 02 测试使用 在使用前需要先安装jd…...
前端零基础入门到上班:【Day4】HTML 多媒体与表单深度教程
HTML 多媒体与表单深度教程 **1. HTML 多媒体基础:深入理解 <video> 和 <audio> 标签****1.1 <video> 标签:详细剖析与用法****1.1.1 基础结构与属性详解****1.1.2 视频格式的兼容性与示例****1.1.3 视频控制的实际应用** **1.2 <a…...
原创作品——银行软件产品界面设计
蓝蓝设计团队服务金融类应用界面设计,以沉稳的色调和简洁的线条营造出专业可靠的氛围。特点在于融入了创新的元素增添界面的活力与现代感。细节处理上,注意数据的视觉呈现效果,采用定制化的图表和清晰的排版,确保用户能够快速理解…...
若依RuoYi-Vue 定时任务 速学
1.若依定时任务模块(ruoyi-quartz) 那么从一个简单的入门示例开始,掌握定时任务的使用吧! 2. 入门示例(学会制作一个简单定时任务) 首先打开定时任务模块中的task包,这里已经有一个已经写好的R…...
【pytest学习】pytest.main()
基本用法## pytest.main()函数是用于启动测试运行的入口点。它可以在命令行中直接使用,也可以在脚本中以编程方式调用。 以下是一个简单的示例: import pytest if __name__"__main__":pytest.main()执行当前目录下的所有测试文件 使用pytes…...
设计模式: Pimpl(Pointer to Implementation)
这种设计模式通常被称为 Pimpl(Pointer to Implementation)惯用法,有时也被称为 Cheshire Cat 惯用法。它主要用于隐藏实现细节和减少编译依赖。 例子: DatabaseConnection.h #ifndef DATABASE_CONNECTION_H #define DATABASE_…...
android开发中文网站 android developer
Android 平台 | Platform | Android Developers 在此做个记录...
实习冲刺Day1
算法题 20. 有效的括号 - 力扣(LeetCode) 这个题我们采用stack栈的方式来进行相应的括号匹配 情况有以下几种 当字符串s中只有一个字符的时候,那这个时候字符串一定是不匹配的所以直接返回false当字符串为发生标准匹配的时候,…...
安全见闻(5)——开阔眼界,不做井底之蛙
安全见闻五:人工智能 内容预览 ≧∀≦ゞ 安全见闻五:人工智能声明导语一、人工智能基础机器学习基础机器学习的典型工作流程1. 数据收集2. 数据预处理3. 模型选择与训练4. 模型评估与优化5. 模型应用 深度学习基础深度学习基本原理1. 神经网络基础2. 多层…...
Navicat 安装
Navicat 安装步骤...
做试管婴儿的网站/百度指数移动版app
源码获取:博客首页 "资源" 里下载! 一、项目简述 功能: 前台: * 用户模块 * 分类模块 * 商品模块 * 购物车模块 * 订单模块 后台: * 管理员模块 * 分类管理模块 * 商品管理模块 * 订单模块…...
建网站必需服务器吗/建站是什么意思
GDB 是我们平时调试 c/c程序的利器, 查起复杂的 bug 问题,比打印大法要好的多,但是也不得不说, gdb 在默认情况下用起来并不是很好用,最近学习到几个高级点的技巧,分享下:一 美化打印先上个例子:#include <stdio.h>typedef struct {int i ;int j;char * str;int array[10…...
石油化工建设网站/收录优美图片topit
除了在学校所学最基本的通过myeclipse中对tomcat进行配置之外,在实际工作中遇到很多不同配置方法。 备忘。 1、在D:\tomcat-6.0.14\conf\Catalina\localhost中进行路径,数据源配置: qhn.xml <?xml version"1.0" encoding&quo…...
无锡专业做网站建设/百度售后服务电话
在我们平常的编码中,通常会将一些对象保存起来,这主要考虑的是对象的创建成本。比如像线程资源、数据库连接资源或者 TCP 连接等,这类对象的初始化通常要花费比较长的时间,如果频繁地申请和销毁,就会耗费大量的系统资源…...
深圳国网站建设/百度推广管理
赋值语句 前面已经说明,要访问内存,就需要相应的地址以表明访问哪块内存,而变量是一个映射,因此变量名就相当于一个地址。对于内存的操作,在一般情况下就只有读取内存中的数值和将数值写入内存(不考虑分…...
网站建设合同纠纷 延期可以终止合同吗/长沙seo管理
方案一: 文件名版本号,区别对待不同的版本控制,有设定值后会加上_v_x的后缀名。如:加载主文件 main.swf, 被命名为:Main_v_60.swf 。 方案二: loader.load(new URLRequest("assets/a.swf?"版本号 或者 随机…...