[一篇读懂]C语言十二讲:栈与队列和真题实战

[一篇读懂]C语言十二讲:栈与队列和真题实战

  • 1. 与408关联解析及本节内容介绍
    • 1 与408关联解析
    • 2 本节内容介绍
  • 2. 栈(stack)的原理解析
    • 2.1 **栈:只允许在一端进行插入或删除操作的线性表**
    • 2.2 栈的基本操作
    • 2.3 栈的顺序存储
    • 2.4 栈的链表存储
  • 3. 初始化栈 - 入栈 - 出栈实战
  • 4. 队列(Queue) - 循环队列原理解析
    • 4.1 **队列:只允许在一端进行插入,而在另一端进行删除的线性表**
    • 4.2 队列的基本操作
    • 4.3 循环队列
      • 循环数列元素入队
      • 循环数列元素出队
    • 4.4 队列的链式存储
      • 存储结构
  • 5. 循环队列实战
  • 6. 队列实战(通过链表实现)
  • 总结
    • 2
    • 3
    • 4
    • 5
    • 6


1. 与408关联解析及本节内容介绍

1 与408关联解析

【2019年队列】
42.(10分)请设计一个队列,要求满足:①初始时队列为空;②入队时,允许增加队列占用空间;③出队后,出队元素所占用的空间可重复使用,即整个队列所占用的空间只增不减;④入队操作和出队操作的时间复杂度始终保持为O(1)。请回答下列问题:
(1)该队列是应选择链式存储结构,还是应选择顺序存储结构?
(2)画出队列的初始状态,并给出判断队空和队满的条件。
(3)画出第一个元素入队后的队列状态。
(4)给出入队操作和出队操作的基本过程。

栈 - 一般为选择题,大题较少;
队列 - 选择题,大题均涉及。

2 本节内容介绍

本节分为六小节讲解,包含栈,队列,循环队列的原理讲解及实战
第一小节是针对栈的原理讲解
第二小节是针对初始化栈-入栈-出栈实战
第三小节是队列-循环队列原理解析
第四小节是循环队列实战
第五小节是队列的实战(通过链表的头插,头部删除实现)
第六小节是2019年42题真题讲解


2. 栈(stack)的原理解析

2.1 栈:只允许在一端进行插入或删除操作的线性表

堆栈(stack)又称为堆叠
栈的特点是:先进后出(First In Last Out)
FILO

2.2 栈的基本操作

(类似电梯)

  • 元素入栈 - 从栈顶(Top)添加一个元素
    元素入栈

  • 元素出栈 - 从栈顶(Top)删除一个元素
    元素出栈

2.3 栈的顺序存储

栈是结构体
用数组存储数据
top是栈顶
顺序存储实现栈

  • 元素入栈&出栈代码实现
//初始化
S.top = -1;//栈为空
//入栈
S.top = S.top + 1;
S.data[S.top] = 1;

S.top = S.top + 1;
S.data[S.top] = 2;

S.top = S.top + 1;
S.data[S.top] = 3;

//可以写成以下形式
//前加加,先做加1,然后再去做后续的
S.data[++S.top] = 4;

//出栈
x = S.data[S.top];
S.top = S.top - 1;

//可以写成以下形式
//后减减
x = S.data[S.top--]
  • 栈满
    S.top等于MaxSize - 1时,栈满

2.4 栈的链表存储

(相对不重要,考的概率极低)

头部插入法和头部删除法
LiStack Lhead = (LiStack)malloc(sizeof(struct Linknode))
Lhead->next = NULL;
在这里插入图片描述>top = (LiStack)malloc(sizeof(struct Linknode));
top->next = NULL;
top->data = 1;
top->next = Lhead->next;
Lhead->next = top;
 
元素出栈
在这里插入图片描述c = top->data;
Lhead->next = top->next;
free(top);
top = Lhead->next;
 
栈空栈满
在这里插入图片描述
Lhead->next == NULL为真,则栈为空
只要存在剩余内存,那么栈就可以继续添加元素


3. 初始化栈 - 入栈 - 出栈实战

代码实战步骤(五步):
初始化栈 - 判断栈是否为空 - 压栈 - 获取栈顶元素 - 弹栈。

注意:S.top为-1时,代表栈为空,每次先对S.top加1后,再放置元素

五个步骤分为五个子函数。
代码演示:

#include <stdio.h>
#include <stdlib.h>

#define MaxSize 50
typedef int ElemType;
typedef struct {
	ElemType data[MaxSize];//数组
	int top;//始终指向栈顶的一个变量
}SqStack;

//初始化栈
void InitStack(SqStack& S)
{
	S.top = -1;//初始化栈,让栈为空

}

//判断栈是否为空
bool StackEmpty(SqStack S)
{
	if (-1 == S.top)
	{
		return true;
	}
	else
	{
		return false;
	}
}

//入栈
bool Push(SqStack &S, ElemType x)
{
	//判断栈是否满了
	if (S.top == MaxSize - 1)
	{
		return false;
	}
	S.data[++S.top] = x;//等价于S.top = S.top + 1;  S.data[S.top] = x;
	return true;
}

//获取栈元素
bool GetTop(SqStack S, ElemType& m)
{
	//判断栈是否为空
	if (StackEmpty(S))
	{
		return false;
	}
	m = S.data[S.top];//拿栈顶元素
	return true;
}

//弹出栈元素
bool Pop(SqStack& S, ElemType& m)
{
	//判断栈是否为空
	if (StackEmpty(S))
	{
		return false;
	}
	m = S.data[S.top--];//出栈 - 先m = S.data[S.top];  S.top = S.top - 1
	return true;
}

int main()
{
	SqStack S;
	InitStack(S);
	bool flag;
	flag = StackEmpty(S);
	if (flag)
	{
		printf("stack is empty\n");
	}
	Push(S, 3);//入栈元素3
	Push(S, 4);//入栈元素4
	Push(S, 5);//入栈元素5
	ElemType m;
	flag = GetTop(S, m);//获取栈顶元素
	if (flag)
	{
		printf("获取栈顶元素为 %d\n", m);
	}
	flag = Pop(S, m);//弹出栈顶元素
	if (flag)
	{
		printf("弹出栈顶元素为 %d\n", m);
	}
	flag = GetTop(S, m);//获取栈顶元素
	if (flag)
	{
		printf("获取栈顶元素为 %d\n", m);
	}
	return 0;
}

运行结果:在这里插入图片描述


4. 队列(Queue) - 循环队列原理解析

4.1 队列:只允许在一端进行插入,而在另一端进行删除的线性表

队列(queue)简称
也是一种操作受限
队的特点是:先进先出(First In First Out)
FIFO

4.2 队列的基本操作

队头(Front)。允许删除的一端,又称队首。
队尾(Rear)。允许插入的一端。
在这里插入图片描述

4.3 循环队列

#define MaxSize 6
typedef int ElemType;
typedef struct{
	ElemType data[MaxSize];//数组,存储MaxSize - 1个元素
	int front,rear;//队列头,队列尾
}SqQueue;

SqQueue Q;

循环队列

  1. Q,front和Q,rear初始化为零,其相等时,循环队列为空。
  2. 放入一个元素后,Q.rear+1;
    出队一个元素后,Q.front+1。
  3. 如果全部放满,Q.front和Q.rear相等,无法判断队满还是队空。
  4. (Q.rear + 1) % MaxSize == Q.front时,判断队满,牺牲一个存储单元

循环数列元素入队

bool Enqueue(SqQueue &Q, ElemType x)
{
	if ((Q.rear + 1) % MaxSize == Q.front)
		return false;
	Q.data[Q.rear] = x;//放入元素
	Q.rear = (Q.rear + 1) % MaxSize;//改变队尾标记
	return true;
}

循环数列元素出队

bool Enqueue(DeQueue &Q, ElemType x)
{
	if (Q.rear == Q.front)
		return false;
	x = Q.data[Q.front];//先进先出
	Q.front = (Q.front + 1) % MaxSize;
	return true;/
}

4.4 队列的链式存储

队列的链式表示称为链队列,它实际上是一个同时带有队头指针和队尾指针单链表。头指针指向队头结点,尾指针指向队尾结点,即单链表的最后一个结点。
在这里插入图片描述

存储结构

typedef int ElemType;
typedef struct LinkNode{
	ElemType data;
	struct LinkNode *next;
}LinkNode;  //链表结点的结构体
typedef struct {
	LinkNode *front, *rear; //链表头 链表尾
}LinkQueue; //先进先出

LinkQueue Q;

相对于原有编写的链表增加了尾指针


5. 循环队列实战

代码实战步骤(四步):
初始化循环队列 - 判断循环队列是否为空 - 入队 - 出队

四个步骤分为四个子函数。
代码演示:

#include <stdio.h>
#include <stdlib.h>


#define MaxSize 5
typedef int ElemType;
typedef struct {
	ElemType data[MaxSize];//数组,存储MaxSize - 1个元素
	int front, rear;//队列头 队列尾
}SqQueue;

void InitQueue(SqQueue& Q)
{
	Q.front = Q.rear = 0;//初始化循环队列,就是让头和尾都指向零号
}

//判断循环队列是否为空
bool IsEmpty(SqQueue Q)
{
	return Q.rear == Q.front;//相等时为空
}

//入队
bool EnQueue(SqQueue& Q, ElemType x)
{
	if ((Q.rear + 1) % MaxSize == Q.front)//判断是否队满 - 满了就不能入队了
	{
		return false;
	}
	Q.data[Q.rear] = x;//放入元素3 4 5 6
	Q.rear = (Q.rear + 1) % MaxSize;//rear要加1,如果大于数组最大下标,要回到开头
	return true;
}

//出队
bool DeQueue(SqQueue& Q, ElemType& x)
{
	if (Q.rear == Q.front)//队列为空,无法出队
	{
		return false;
	}
	x = Q.data[Q.front];//出队
	Q.front = (Q.front + 1) % MaxSize;
	return true;
}

//循环队列的代码实战
int main()
{
	SqQueue Q;
	bool ret;//存储返回值
	ElemType element;//存储出队元素
	InitQueue(Q);
	ret = IsEmpty(Q);
	if (ret)
	{
		printf("SqQueue is empty\n");
	}
	else
	{
		printf("SqQueue is not empty\n");
	}
	EnQueue(Q, 3);//入队3
	EnQueue(Q, 4);
	EnQueue(Q, 5);
	ret = EnQueue(Q, 6);
	ret = EnQueue(Q, 7);//队满,7无法入队
	if (ret)
	{
		printf("EnQueue successful\n");
	}
	else
	{
		printf("EnQueue failed\n");
	}
	ret = DeQueue(Q, element);//出队
	if (ret)
	{
		printf("DeQueue successful,element = %d\n",element);
	}
	else
	{
		printf("DeQueue failed\n");
	}
	ret = DeQueue(Q, element);//出队
	if (ret)
	{
		printf("DeQueue successful,element = %d\n", element);
	}
	else
	{
		printf("DeQueue failed\n");
	}
	ret = EnQueue(Q, 8);//前面出队了元素,8可以入队
	if (ret)
	{
		printf("EnQueue successful\n");
	}
	else
	{
		printf("EnQueue failed\n");
	}
	return 0;
}

运行结果:在这里插入图片描述


6. 队列实战(通过链表实现)

代码实战步骤(三步):
初始化队列 - 入队 - 出队


总结

2

  • 头插法新建链表流程图:
    1

3

  • 尾插法新建链表流程图:
    1

4

  • 按位置查找流程图:1

5

  • 往第i个位置插入元素流程图:
    1

6

  • 链表中每一个结点在内存中是不连续的,通过单步调试,在变量窗口,依次点开头指针L,观察每一个结点是否符合自己的预期。

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

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

相关文章

MySQL学习笔记

一、mysql环境安装 服务管理工具&#xff08;省略&#xff09; 二、Mysql DB2 Sybase Oracle SQL Server Mysql Access MangoDB(noSQL) Apache/nginx服务器&#xff1a; LAMP LinuxApacheMysqlPHP LNMP LinuxNginxMysqlPHP WAMP windowApacheMysqlPHP SQL: DDL(数据定…

【进程间通信 之 通信的建立】

目录&#xff1a; 前言进程间通信的目的进程间通信的方式管道1.匿名管道简单示例1 - 消息传输五个特性四种场景简单示例2 - 进程控制对管道的深入理解 2.命名管道简单示例3 -- 不相关进程间通信 system V共享内存简单示例4 - 通知事件消息传输 总结 前言 打怪升级&#xff1a;…

MyBatis学习 (一) 配置文件解析流程

MyBatis源码学习 最近在学习MyBatis的代码。记录下 首先下载下源码&#xff1a; https://github.com/mybatis/parent https://github.com/mybatis/mybatis-3 parent为父控依赖。也需要下载。 入口 InputStream inputStream null; try {// 获取配置文件inputStream Reso…

为AIGC敲响警钟!千亿级赛道为何成了作恶温床?

‍数据智能产业创新服务媒体 ——聚焦数智 改变商业 随着人工智能通用大模型的问世&#xff0c;全球对AIGC技术的强大潜力有了更加深刻的认识。然而&#xff0c;这也引发了诸多关于AIGC技术可信度、隐私保护以及知识产权等问题的争议&#xff0c;引起了广泛关注。 5月9日&…

开源单用户客服系统源码-上传附件功能-elementui 异步上传文件【唯一客服开发商】...

之前开源的单用户客服系统&#xff0c;上传附件成功后&#xff0c;还不能展示出文件形式&#xff0c;今天把上传展示出文件形式给开发完善一下。 我想要实现的效果是&#xff0c;展示出文件的名称和大小信息 后端返回一个带有文件信息的json结果&#xff0c;前端把该信息组织一…

ubuntu系统配置大恒相机驱动并读取ros话题

文章目录 0. 说明1. 安装大恒相机sdk1.1 下载1.2 安装sdk(用于配置ip和调试相机参数)(1) 电脑网卡配置(网卡固定ip)(2)查看相机图像以及配置相机参数 2. 安装ros驱动包(注&#xff1a;大恒相机官方没ros驱动)2.0 正确流程2.1 错误示范2.1 报错1--缺包2.2 报错2--包编译顺序问题…

arduino 导入 Brain 库

一、引言 最近在做一个可以用脑电波控制的arduino小车&#xff0c;需要用到Brain这个库&#xff0c;而且需要自己导入才能使用。之前试了很多方法&#xff0c;导入成功了&#xff0c;过了几个月又忘记怎么导入了&#xff0c;今天想起来记录一下&#xff0c;好记性不如烂笔头。 …

Java集合类

目录 一、整体架构图 二、List集合类(有序的&#xff0c;可重复的) 1.顺序列表ArrayList 2.链式列表LinkedList 三、Set集合类(不可重复) 1.HashSet(哈希集合) 2.LinkedHashSet(链式哈希集合) 3.TreeSet(树形集合) 四、Map集合类(无序&#xff0c;键唯一&#xff0c;值…

MySQL实战之主从数据同步机制

主从同步的重要性&#xff1a; 解决数据可靠性的问题需要用到主从同步&#xff1b;解决 MySQL 服务高可用要用到主从同步&#xff1b;应对高并发的时候&#xff0c;还是要用到主从同步。 一、MySQL 主从同步流程 当客户端提交一个事务到 MySQL 的集群&#xff0c;直到客户端收…

跨域时怎么处理 cookie?

前言 一个请求从发出到返回&#xff0c;需要浏览器和服务端的协调配合。浏览器要把自己的请求参数带给服务端&#xff0c;服务端校验参数之后&#xff0c;除了返回数据&#xff0c;也可能会顺便把请求是否缓存&#xff0c;cookie等信息告诉浏览器。当请求是跨域请求的时候&…

项目调研 | Loopring研究报告

一、项目简介及愿景 Loopring协议是一个专为应用程序开发的 zkRollup 协议、一个中继器、一个 L2 非托管交易所、一个智能钱包。用户可以在其中使用、交易和存储资产&#xff0c;同时让资产获得增长。 上述Loopring这些Title具体详情如下&#xff1a; 作为协议&#xff0c;Loop…

[Golang] 设计模式以及单例设计模式实例实现

&#x1f61a;一个不甘平凡的普通人&#xff0c;致力于为Golang社区和算法学习做出贡献&#xff0c;期待您的关注和认可&#xff0c;陪您一起学习打卡&#xff01;&#xff01;&#xff01;&#x1f618;&#x1f618;&#x1f618; &#x1f917;专栏&#xff1a;算法学习 &am…

金3银四结束了,回顾一下我2个月面试的公司....

金三银四结束了&#xff0c;还没有 offer 的同学不要气馁&#xff0c;该来的迟早会来。楼主从 年底 月有想法跳槽开始准备春招&#xff0c;一开始也是惨不忍睹&#xff0c;后来慢慢进入状态最近的面试基本都能走到终面&#xff0c;所以好好坚持&#xff0c;最后一定会有好结果的…

Pandas + ChatGPT 超强组合,pandas-ai :交互式数据分析和处理新方法

Python Pandas是一个为Python编程提供数据操作和分析功能的开源工具包。这个库已经成为数据科学家和分析师的必备工具。它提供了一种有效的方法来管理结构化数据(Series和DataFrame)。 在人工智能领域&#xff0c;Pandas经常用于机器学习和深度学习过程的预处理步骤。Pandas通过…

基于主从博弈的综合能源服务商动态定价策略研究(Matlab代码实现)

&#x1f4a5;&#x1f4a5;&#x1f49e;&#x1f49e;欢迎来到本博客❤️❤️&#x1f4a5;&#x1f4a5; &#x1f3c6;博主优势&#xff1a;&#x1f31e;&#x1f31e;&#x1f31e;博客内容尽量做到思维缜密&#xff0c;逻辑清晰&#xff0c;为了方便读者。 ⛳️座右铭&a…

在滴滴和字节跳动划水4年,过于真实了...

先简单交代一下吧&#xff0c;沅哥是某不知名211的本硕&#xff0c;18年毕业加入滴滴&#xff0c;之后跳槽到了头条&#xff0c;一直从事测试开发相关的工作。之前没有实习经历&#xff0c;算是四年半的工作经验吧。 这四年半之间他完成了一次晋升&#xff0c;换了一家公司&am…

如何利用python实现灰色关联分析?

1.灰色关联分析简介 灰色系统这个概念是相对于白色系统和黑色系统而言的。从控制论的知识里&#xff0c;颜色一般代表对于一个系统我们已知信息的多少&#xff0c;白色代表信息量充足&#xff0c;黑色代表我们其中的构造并不清楚的系统&#xff0c;而灰色介于两者之间&#xf…

LabVIEWCompactRIO 开发指南18 使用网络流发送消息和命令

LabVIEWCompactRIO 开发指南18 使用网络流发送消息和命令 默认情况下&#xff0c;网络流旨在最大化吞吐量&#xff0c;但可以轻松实现它们以最大化发送命令或消息的低延迟。 为本部分提供LabVIEW示例代码 命令发送器体系结构 命令发送器是CompactRIO控制器必须响应的任何命…

pga_aggregate_limit和process关系

之前部署19c时&#xff0c;配置pga_aggregate_limit都是直接配置成0了&#xff0c;配置processes的大小也比较随意&#xff0c;上周维护一个客户安装的环境&#xff0c;重启数据库数据库时告警了&#xff0c;才第一次认真对面了 SYSorcl1> startup ; ORA-00093: pga_aggreg…

无代码时代来了,程序员会失业吗?不,程序员又不够用了!

有人问我无代码时代来了&#xff0c;程序员会失业吗&#xff1f;太难了&#xff0c;秃了头就算了&#xff0c;连工作也保不住了&#xff1f; 先说观点&#xff1a;并不会 因为&#xff0c;无代码不是真正意义上的无代码。 无代码开发的使用对象是编程小白&#xff08;我猿是…