重生之“我打数据结构,真的假的?”--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语言中,栈和队列可以通过数组或链表来实现,每种实现方式都有其优缺点。

在理解了这些数据结构的基本操作后,可以更好地应用它们来解决实际问题,如表达式求值、任务调度、图遍历等。掌握这些基础数据结构也为进一步学习更加复杂的数据结构(如树、图等)打下了坚实的基础。

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

智能汽车制造:海康NVR管理平台/工具EasyNVR多品牌NVR管理工具/设备实现无插件视频监控直播方案

一、背景介绍 近年来&#xff0c;随着网络在我国的普及和深化发展&#xff0c;企业的信息化建设不断深入&#xff0c;各行各业都加快了信息网络平台的建设&#xff0c;大多数单位已经或者正在铺设企业内部的计算机局域网。与此同时&#xff0c;网络也成为先进的新兴应用提供了…

详细尝鲜flutter

flutter 161由于官方的汉化文档感觉还是有很多没有汉化的地方 &#xff0c;所以自己打一遍的同时写下了以下笔记 社区生态 官方文档 所有的控件:Widget 目录 | Flutter 中文文档 - Flutter 中文开发者网站 - Flutter 官方论坛的教程 Flutter Widget框架概述 - Flutter中文网…

7款视频转换器大测评!哪款是最适合你的视频格式转换器?

视频已成为我们生活中不可或缺的一部分&#xff0c;但不同的设备、平台和软件往往支持不同的视频格式&#xff0c;这给我们的视频分享、编辑和播放带来了不少困扰。因此&#xff0c;一款高效、易用的视频格式转换器成为了许多人的必备工具。本文将从软件界面、功能特性、难易程…

不推荐使用Scilab作为MATLAB的开源替代

安装了Scilab2024.1.0&#xff0c;随便试了几分钟就发现有严重影响使用的Bug(也可能是就是这样设计的&#xff0c;有一个所谓的“暂停模式”)&#xff0c;复现步骤&#xff1a;主界面上点击“Scilab示例”按钮&#xff0c;打开“演示”窗口&#xff0c;点击左侧列表中的“多项式…

JSON Web Token (JWT)的简单介绍、验证过程及令牌刷新思路

目录 一、JWT 1、什么是Jwt 2、为什么要使用Jwt 3、应用场景 4.Jwt的组成 4.1、Header 4.2、Payload 4.3、signature 二、Jwt验证过程 1、生成Jwt令牌 2、解析旧的Jwt 3、复制Jwt 4、Jwt有效时间测试 三、Jwt令牌刷新思路 1、配置JwtFilter过滤器 2、登录生成Jwt令…

R语言机器学习遥感数据处理与模型空间预测技术及实际项目案例分析

随机森林作为一种集成学习方法&#xff0c;在处理复杂数据分析任务中特别是遥感数据分析中表现出色。通过构建大量的决策树并引入随机性&#xff0c;随机森林在降低模型方差和过拟合风险方面具有显著优势。在训练过程中&#xff0c;使用Bootstrap抽样生成不同的训练集&#xff…

【案例75】全表扫描导致系统崩溃

问题现象 顾问反馈系统审批单据时&#xff0c;系统出现整体卡顿。操作审批单据本身比较长&#xff0c;在数据库中出现了死锁&#xff0c;死锁处理后&#xff0c;一审批单据就又会整体卡顿。 问题分析 开始怀疑有事务锁未释放导致的&#xff0c;先排查数据库当时的状态。发现…

AI写PPT工具:四款人工智能软件全面解析!!

嘿&#xff0c;小伙伴们&#xff01;今天咱们来聊聊那些能帮我们搞定PPT的神器——四款人工智能软件。有了它们&#xff0c;咱们再也不用为做PPT而头疼啦&#xff01; 第一款&#xff1a;笔灵AIPPT 直通车&#xff08;粘贴复制到网站打开&#xff09;&#xff1a;ibiling.c…

C++第八讲:STL--stack和queue的使用及模拟实现

C第八讲&#xff1a;STL--stack和queue的使用及模拟实现 1.stack的使用2.queue的使用3.栈和队列OJ题3.1题目1&#xff1a;最小栈3.2题目2&#xff1a;栈的压入、弹出序列3.3题目3&#xff1a;逆波兰表达式求值3.4题目4&#xff1a;用栈实现队列 4.栈的模拟实现5.队列的模拟实现…

103、QT搭建Excel表环境-使用Qtxlsx库

环境搭建 文件下载 下载QtXlsx源码&#xff1a;https://github.com/dbzhang800/QtXlsxWriter 下载的内容里面的目录结构如下&#xff1a; 搭建perl环境 官网链接: https://strawberryperl.com/ 下载后并安装 检验是否有perl环境的方法&#xff1a; perl --version安装前检…

Go语言基础教程:闭包

在这篇教程中&#xff0c;我们将通过一段简单的 Go 语言代码来理解闭包的概念。闭包是编程中非常强大且常用的工具&#xff0c;尤其适合实现像计数器这样的逻辑。我们将逐行讲解代码&#xff0c;并理解如何在 Go 中利用闭包来保存函数状态。 package mainimport "fmt&quo…

使用QT绘图控件QCustomPlot绘制波形图

使用QT绘图控件QCustomPlot绘制波形图 下载QCustomPlot 下载QCustomPlot,链接路径 解压之后就能看到源代码了 在Qt中添加QCustomPlot的帮助文档 在Qt Creator的菜单:工具–>选项–>帮助–>文档–>添加qcustomplot\documentation\qcustomplot.qch文件。

提升产品竞争力之--IPD产品成本篇

在汉捷的咨询过程中&#xff0c;很多企业老总交流时都会提起这个抱怨&#xff1a;“现在产品竞争太激烈了&#xff0c;客户买产品首先看价格&#xff0c;你价格高一点就买别家的啦……” 汉捷咨询在前文谈到“通过定义产品包需求&#xff0c;来提升产品竞争力。差异化开发&…

【OpenAI】第二节(Token)关于ChatGPT的Token你了解多少?最全Token讲解过程!

在当今的人工智能领域&#xff0c;GPT&#xff08;Generative Pre-trained Transformer&#xff09;无疑是最受关注的技术之一。无论是在文本生成、对话系统&#xff0c;还是在内容创作中&#xff0c;GPT都展现出了强大的能力。然而&#xff0c;很多人对GPT的工作原理仍然存在疑…

MobileViT模型实现图像分类

项目源码获取方式见文章末尾&#xff01; 回复暗号&#xff1a;13&#xff0c;免费获取600多个深度学习项目资料&#xff0c;快来加入社群一起学习吧。 **《------往期经典推荐------》**项目名称 1.【Bi-LSTM-CRF实现中文命名实体识别工具(TensorFlow)】 2.【卫星图像道路检测…

跨界创新|使用自定义YOLOv11和Ollama(Llama 3)增强OCR文本识别

《博主简介》 小伙伴们好&#xff0c;我是阿旭。专注于人工智能、AIGC、python、计算机视觉相关分享研究。 ✌更多学习资源&#xff0c;可关注公-仲-hao:【阿旭算法与机器学习】&#xff0c;共同学习交流~ &#x1f44d;感谢小伙伴们点赞、关注&#xff01; 《------往期经典推…

DevOps实践:在GitLab CI/CD中集成静态分析Helix QAC的工作原理与优势

基于云的GitLab CI/CD平台使开发团队能够简化其CI/CD流程&#xff0c;并加速软件开发生命周期&#xff08;SDLC&#xff09;。 将严格的、基于合规性的静态分析&#xff08;如Helix QAC所提供&#xff09;作为新阶段添加到现有的GitLab CI/CD流程中&#xff0c;将进一步增强SD…

如何使用 NumPy 和 Matplotlib 进行数据可视化

如何使用 NumPy 和 Matplotlib 进行数据可视化 在数据科学领域&#xff0c;NumPy 和 Matplotlib 是 Python 中最常用的两个库。NumPy 用于科学计算和数据处理&#xff0c;而 Matplotlib 提供了丰富的图表工具来展示数据。本文将介绍如何将这两个库结合使用&#xff0c;轻松进行…

现货黄金怎么交易能快速入门?

现货黄金交易的核心在于以小博大&#xff0c;即用较小的亏损去搏击较大的利润&#xff0c;成功不仅要靠资金上的管理&#xff0c;更需要心态和策略的支持。现货黄金交易的过程也是人性修炼的过程&#xff0c;新手投资者不仅要学会交易技巧&#xff0c;更需要学会控制情绪&#…

sql server 行转列及列转行

图1 图2 1.行转列 &#xff08;图1->图2&#xff09; 1.方法一 (数据库通用&#xff09;&#xff0c;使用max 加case when 函数 -- 行转列 图1->图2 SELECT name,MAX(CASE WHEN subject语文 THEN score ELSE 0 END) AS "语文",MAX(CASE WHEN subject数学 …