数据结构之栈与队列的实现与详细解析

个人主页:点我进入主页

专栏分类:C语言初阶      C语言程序设计————KTV       C语言小游戏     C语言进阶

C语言刷题       数据结构初阶

欢迎大家点赞,评论,收藏。

一起努力,一起奔赴大厂。

目录

1.前言

2.栈

2.1栈的概念与性质

2.2栈的实现

3.队列

3.1队列的概念

3.2队列的实现

4.练习

4.1编程

4.2概念


1.前言

        在前面我们写了关于链表和顺序表的内容,我们很容易知道顺序表相当于数组,链表是不连续的空间连在一起,顺序表和链表是我们学习数据结构的一个重要的基础,今天我们主要讲解的是两个重要的结构栈和队列,这两个结构既可以使用顺序表实现也可以使用链表实现,顺序表和链表哪一个更好呢?这需要我们知道栈和队列是如何进行数据的存储的,这与他们数据存储的性质有关,接下来让我们看看栈与队列的具体实现吧。

2.栈

2.1栈的概念与性质

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

栈满足数据的先进后出的原则,例如我们让1,2,3,4,5依次入栈,我们出栈先出栈的是数字5。既然栈是先进后出我们用数组进行数据的存储还是用链表进行数据的存储呢,先进后出也就是说我们呢访问需要栈知道栈顶的位置,但是我们在数据入栈时链表相对来说比较困难,所有我们在选择栈的存储时一半使用数组。

2.2栈的实现

        在栈的操作中,我们包括栈的初始化,入栈,出栈,栈空,增容,取栈顶元素,栈中元素个数,遍历,释放空间这几个操作。

void InItStack(Stack* s)
{assert(s);s->capacity = 4;s->top = -1;s->data = (char*)malloc(sizeof(char) * s->capacity);
}
void CheckCapacity(Stack* s)
{assert(s);if (s->top + 1 == s->capacity)s->capacity += 2;char* p = (char*)realloc(s->data, sizeof(char) * s->capacity);if (p == NULL){perror("realloc fail");return;}elses->data = p;
}
void StackPush(Stack* s, char ch)
{assert(s);CheckCapacity(s);s->data[++s->top] = ch;
}
bool StackEmpty(Stack* s)
{assert(s);if (s->top == -1)return true;return false;
}
char StackPop(Stack* s)
{assert(s);if (!StackEmpty(s)){s->top--;return s->data[s->top + 1];}return '1';
}
void StackDestory(Stack* s)
{assert(s);free(s->data);
}
int StackSize(Stack* s)
{assert(s);return s->top + 1;
}
int StackTopdata(Stack* s)
{assert(s);return s->data[s->top];
}

        在函数实现时我们有几点需要注意,首先我们需要将栈顶初始化为-1,主要原因是如果我们初始化为0的话,栈为空判断起来比较麻烦,初始化为-1就很容易判断。还有就是当我们操作执行完后我们需要将空间进行释放。

3.队列

3.1队列的概念

队列:只允许在一端进行插入数据操作,在另一端进行删除数据操作的特殊线性表,队列具有先进先出FIFO(First In First Out) 入队列:进行插入操作的一端称为队尾 出队列:进行删除操作的一端称为队头。队列也可以数组和链表的结构实现,使用链表的结构实现更优一些,因为如果使用数组的结构,出队列在数组头上出数据,效率会比较低。

3.2队列的实现

        在队列的操作中我们包括对队列的初始化,队列节点的创建,出队,入队,取队顶元素,对空,遍历,队列元素个数,释放空间。

typedef struct QNode {int data;struct QNode* next;
}QNode;
typedef struct Queue {struct QNode* head;struct QNode* tail;
}Queue;
void QueueInit(Queue* q)
{assert(q);q->head = NULL;q->tail = NULL;
}
QNode* QueueCreate(Queue* q, int x)
{QNode* newnode = (QNode*)malloc(sizeof(QNode));if (newnode == NULL){perror("malloc fail");return NULL;}newnode->data = x;newnode->next = NULL;return newnode;
}
void QueuePush(Queue* q, int x)
{QNode* newnode = QueueCreate(q, x);if (q->head == NULL){q->head = newnode;q->tail = newnode;}else{q->tail->next = newnode;q->tail = newnode;}
}
bool QueueEmpty(Queue* q)
{return q->head == NULL;
}
int QueuePop(Queue* q)
{assert(q);if (!QueueEmpty(q)){int data = q->head->data;if (q->head == q->tail){free(q->head);q->head = q->tail = NULL;}else{QNode* cur = q->head->next;free(q->head);q->head = cur;}return data;}
}
int QueueSize(Queue* q)
{int count = 0;QNode* cur = q->head;while (cur){count++;cur = cur->next;}return count;
}
void QueueDestory(Queue* q)
{assert(q);if (!QueueEmpty(q)){QNode* cur = q->head->next;QNode* prev = q->head;while (prev){free(prev);prev = cur;if (cur){cur = cur->next;}}}
}
void QueuePrint(Queue* q)
{assert(q);QNode* cur = q->head;while (cur){printf("%d ", cur->data);cur = cur->next;}
}
int top(Queue* q)
{assert(q);if (!QueueEmpty(q)){return q->head->data;}
}

        在队列中我们需要注意几点,我们在传参数时传的是一级指针,我们在前面写链表时我们都是传的二级指针,而且我们也是对头指针进行操作,为什么会传一级指针呢?这主要就是我们创建了两个结构体,第一个结构体储存数据,第二个结构体储存头尾指针,我们传的时第二个结构体的地址,传结构体当然是一级指针了为什么在前面我们使用了二级指针呢?这主要是我们返回值是void类型,我们知道函数在进行传参时会将传送的参数拷贝一份,这一份也就是我们在函数中进行操作的数据,我们对指针内容进行修改,如果修改的不是头指针,不会出现任何问题,但是我们一旦修改头指针的位置,那么就会出现错误。

4.练习

4.1编程

1. 括号匹配问题。OJ链接
2. 用队列实现栈。OJ链接
3. 用栈实现队列。OJ链接
4. 设计循环队列。OJ链接

4.2概念

1.一个栈的初始状态为空。现将元素1、2、3、4、5、A、B、C、D、E依次入栈,然后再依次出栈,则元素出
栈的顺序是( )。
A 12345ABCDE
B EDCBA54321
C ABCDE12345
D 54321EDCBA
2.若进栈序列为 1,2,3,4 ,进栈过程中可以出栈,则下列不可能的一个出栈序列是()
A 1,4,3,2
B 2,3,4,1
C 3,1,4,2
D 3,4,2,1
3.循环队列的存储空间为 Q(1:100) ,初始状态为 front=rear=100 。经过一系列正常的入队与退队操作
后, front=rear=99 ,则循环队列中的元素个数为( )
A 1
B 2
C 99
D 0或者100
4.以下( )不是队列的基本运算?
A 从队尾插入一个新元素
B 从队列中删除第i个元素
C 判断一个队列是否为空
D 读取队头元素的值
5.现有一循环队列,其队头指针为front,队尾指针为rear;循环队列长度为N。其队内有效长度为?(假设
队头不存放数据)
A (rear - front + N) % N + 1
B (rear - front + N) % N
C ear - front) % (N + 1)
D (rear - front + N) % (N - 1)
 

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

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

相关文章

ISO27000认证实施意义

在信息化时代,信息安全对于企业至关重要。ISO27000认证作为信息安全管理体系的标准,其实施意义愈发凸显。本文将围绕ISO27000认证,详细解答其实施意义,并探讨ISO27001认证范围、价格、含义以及与ISO27000的关系等。 一、ISO27000…

怎么做excel表格的二维码?文件快速做二维码的教程

Excel表格怎么做成二维码来扫码插看呢?Excel是工作中常用的一种文件格式,想要将表格内容分享给其他人查看,那么将表格生成二维码的方法会更加的方便快捷,其他人只需要扫描二维码就可以查看或者下载文件。表格excel二维码可以通过文…

如何找出excel中两列数据中不同的值(IF函数的用法)

第一部分,举例: 例1: 如下图所示,A列和B列是需要比较的数据,C列为对比规则:IF(A2B2,"是","否") 示例图 例2:给B列的成绩评等级 C列的规则: IF(B2>85,&qu…

【一周安全资讯1125】《工业和信息化领域数据安全行政处罚裁量指引 (试行)》公开征求意见;中国台湾大江生医泄露236GB数据

要闻速览 1、《工业和信息化领域数据安全行政处罚裁量指引 (试行)》公开征求意见 2、年度最大安全事件:MOVEit黑客攻击波及2600多家企业 3、美国核研究实验室遭黑客入侵,数十万个人数据泄漏 4、大英图书馆遭受勒索攻击,业务完全恢复需要数周…

Matplotlib画图接口_Python数据分析与可视化

Matplotlib画图接口 导入matplotlib显示图像画图接口 导入matplotlib 和numpy,pandas一样,在导入matplotlib时我们也可以用一些常用的简写形式: import matplotlib as mpl import matplotlib.pyplot as pltpyplot是最常用的画图模块接口,功…

哈希表、哈希冲突解决办法

文章目录 一、什么是哈希表?二、什么是哈希冲突?怎样解决?三、哈希表的大小为什么是质数?四、链表法五、开放地址法线性探测法平方探测法双哈希(Double Hashing) 六、哈希表满了怎么办?七、完美哈希八、一些使用哈希解…

机器学习基础Matplotlib绘图

一、运行环境 学习工具:jupyter-notebookpython版本:311系统:Win11 二、什么是matplotlib? matplotlib是基于python生态开发的一个可视化绘图库,它的出现让python在数据分析及机器学习方面占了重要的一部分&#…

springBoot的实现原理;SpringBoot是什么;使用SpringBoot的核心功能;springBoot核心注解以及核心配置文件

文章目录 springBootspringBoot的实现原理什么是 Spring Boot?SpringBoot是什么为什么要使用springBootSpring Boot的核心功能Spring Boot 主要有如下优点: SpringBoot启动过程-流程Spring Boot 的核心注解是哪个?什么是 JavaConfig&#xff…

echarts 通用线性渐变堆叠面积图

echarts 通用线性渐变堆叠面积图 getLineData2() {const myChart echarts.init(this.$refs.chartDom);const option {tooltip: {trigger: axis,},legend: {show: false,textStyle: {fontSize: 14, //字体大小color: #ffffff, //字体颜色},data: [AAA, BBB],},grid: {show: tr…

汽车功能安全ISO26262

一、功能安全基本概念及功能安全管理 什么是功能安全 相关标准: 现状: 功能安全的目的和范围: 总体框架: 基本定义:

TypeError: ‘_io.TextIOWrapper’ object is not subscriptable

TypeError: ‘_io.TextIOWrapper’ object is not subscriptable表示文件不能用下标进行索引。改正代码如下即可正常运行: 错误代码示范: file_name /test.txt with open(file_name,r, encodingutf-8) as name:a name[1] #取name的第二行数据 改正之…

下载文件并重命名

//下载文件并重命名 // 无需数字化归档模版下载 function nodigitalMeth(){ let filenameunescape("/projectapp/ghsjy/template/noNeedDigital.docx")//原文件为英文名字 downloadFileRename(filename,"无需成果数据汇交模版") } // 需要数字化归档模版下…

有哪些可信的SSL证书颁发机构?

目前市面上所显示的SSL证书颁发机构可所谓不计其数,类型也是多样,就好比我们同样是买一件T恤,却有百家不同类型的店铺一个道理。根据CA里面看似很多,但能拿到99%浏览器及设备信任度的寥寥无几,下面小编整理出几家靠谱可…

MySQL 教程 1.3

上期网友笔记整理 记录 MySQL 学习过程遇到的问题。 系统:win32 位 MySQL 版本:5.7.17-log MySQL 语法对大小写不敏感,但是大写更容易看出。 一、启动关闭MySQL服务 1【开始菜单】搜索 services.msc 打开 windows【服务管理器】&#xf…

docker (简介、dcoker详细安装步骤、常用命令)- day01

一、 为什么出现 Docker是基于Go语言实现的云开源项目。 Docker的主要目标是“Build,Ship and Run Any App,Anywhere”,也就是通过对应用组件的封装、分发、部署、运行等生命周期的管理,使用户的APP(可以是一个WEB应用或数据库应…

【代码】考虑电解槽变载启停特性与阶梯式碳交易机制的综合能源系统优化调度matlab-yalmip-cplex/gurob

程序名称:考虑电解槽变载启停特性与阶梯式碳交易机制的综合能源系统优化调度 实现平台:matlab-yalmip-cplex/gurobi 代码简介:提出了一种考虑 变载启停特性的电解槽混合整数线性模型,根据电 氢负荷可以实时调整设备工作状态&…

视频格式转换:将MP4轻松转MKV格式,高效便捷

随着科技的发展,数字媒体已经深入到生活中,视频格式的转换也成为了许多人的日常要求。MP4和MKV是两种常见的视频格式,它们各有优点。MP4以其高效的压缩比和广泛的兼容性被广泛使用,而MKV则因其强大的封装能力和无损压缩而受到喜爱…

英语语法:连词or, and, if, unless怎么用?

连词or, and, if, unless怎么用?1. or conj. 或者,还是, 和, 否则用法:并列连词①当“或者,还是”讲时,用在选择疑问句中,是选择疑问句的标志例:Are you a teacher or a …

阻塞队列介绍(二)

3 LinkedBlockingQueue 3.1 LinkedBlockingQueue的底层实现 查看LinkedBlockingQueue是如何存储数据&#xff0c;并且实现链表结构的。 // Node对象就是存储数据的单位 static class Node<E> { // 存储的数据 E item; // 指向下一个数据的指针 Node<E> next; //…

C++多线程学习(三):锁资源管理和条件变量

参考引用 C11 14 17 20 多线程从原理到线程池实战代码运行环境&#xff1a;Visual Studio 2019 1. 利用栈特性自动释放锁 RAII 1.1 什么是 RAII RAII (Resource Acquisition Is Initialization)&#xff1a;使用局部对象来管理资源的技术称为资源获取即初始化 它的生命周期是…