【数据结构】24王道考研笔记——栈、队列和数组

news2024/11/17 21:29:51

三、栈、队列和数组

目录

  • 三、栈、队列和数组
      • 基本概念
      • 顺序栈
      • 链式栈
    • 队列
      • 基本概念
      • 顺序存储
      • 链式存储
      • 双端队列
    • 应用
      • 括号匹配
      • 前中后缀表达式
      • 栈在递归中的运用
      • 队列的运用
    • 数组
      • 数组的存储
      • 对称矩阵
      • 三角矩阵
      • 三对角矩阵
      • 稀疏矩阵

基本概念

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

  • 栈顶:线性表允许进行插入删除的那一端
  • 栈底:固定的,不允许进行插入删除的那一端
  • 空栈:不含任何元素的空表

特点:先进后出

image.png

基本操作:

image.png

常考题型:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-yAQLivaR-1686635232177)(null)]

顺序栈

结构体:

//结构体
#define MaxSize 10 //定义栈中元素的最大个数
typedef struct
{
	int data[MaxSize];//静态数组存放栈中元素
	int top;//栈顶指针
} SqStack;

初始化:

//初始化
void InitStack(SqStack& S)
{
	S.top = -1;//初始化栈顶指针 若为0.则指向下一个插入的位置
}

判空:

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

进栈:

//进栈
bool Push(SqStack& S, int x)
{
	if (S.top == MaxSize - 1)//栈满,报错
		return false;
	S.top = S.top + 1;//先加1
	S.data[S.top] = x;//新元素入栈 这两行等价于S.data[++S.top]=x;
	return true;
}

出栈:

//出栈
bool Pop(SqStack& S, int& x)
{
	if (S.top == -1) return false;//栈空,报错
	x = S.data[S.top];//栈顶元素先出栈
	S.top = S.top - 1;//指针再减一 这两行等价于 x=S.data[S.top--]
	return true;
}

获取栈顶元素:

//读取栈顶元素
bool GetTop(SqStack& S, int& x)
{
	if (S.top == -1) return false;//栈空,报错
	x = S.data[S.top];//栈顶元素出栈
	return true;
}

让top指向待插入位置的写法:(初始化top=0)

image.png

缺点:栈的大小不可变

可以使用共享栈进行优化,提高内存运用率。

image.png

共享栈定义:

//共享栈
typedef struct
{
	int data[MaxSize]; //静态数组存放栈中元素
	int top0; //0号栈栈顶指针
	int top1; //1号栈栈顶指针
} ShStack;

//初始化共享栈
void InitStack(ShStack& S)
{
	S.top0 = -1;
	S.top1 = MaxSize; 
	//栈满条件为top0+1==top1
}

链式栈

链式栈的构建和单链表十分相似,主要限制与进栈出栈都只能在栈顶一端进行(链头作为栈顶)

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Qpnymbqf-1686635230993)(null)]

结构体:

# define MaxSize 10
typedef struct LinkNode {
    int data;
    struct LinkNode* next;
} *LinkStack;

初始化:

//初始化
bool InitStack(LinkStack& LS) {
    LS = (LinkNode*)malloc(sizeof(LinkNode));//分配一个头节点
    if (LS == NULL) {
        return false;
    }
    LS->next = NULL;
    return true;
}

入栈:

//入栈
bool Push(LinkStack& LS, int t) {
    LinkNode* s = (LinkNode*)malloc(sizeof(LinkNode));
    if (s == NULL)return false;
    s->data = t;
    s->next = LS->next;
    LS->next = s;
    return true;
}

出栈:

//出栈
bool Pop(LinkStack& LS, int& x) {
    //判断
    if (LS->next == NULL)return false;//栈空,这里的条件
    LinkNode* q;
    q = LS->next;
    LS->next = q->next;
    x = q->data;
    free(q);
    return true;
}

获取栈顶元素:

//获取栈顶元素
bool GetTop(LinkStack LS, int& x) {
    if (LS == NULL)return false;
    x = LS->next->data;
    return true;
}

队列

基本概念

队列是只允许在一端进行插入,在另一端删除操作的线性表。(分别称为入队,出队)

  • 特点:先进先出,后进后出(FIFO)
  • 队头:允许删除的一端
  • 队尾:允许插入的一端

基本操作:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Do0UhQza-1686635229210)(C:\Software\PicGo\1683358362151.png)]

顺序存储

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-pZhiTig2-1686635230819)(null)]

结构体:

#define MaxSize 10 //定义队列中元素的最大个数
typedef struct
{
	int data[MaxSize];//用静态数组存放队列元素、
	int front, rear;//队头指针和队尾指针
} SqQueue;

初始化:

//初始化队列
void InitQueue(SqQueue& Q)
{
	//初始,队头队尾指针指向0
	Q.front = Q.rear = 0;//队尾指针始终指向下一个插入的位置
}

判空:

//判空
bool QueueEmpty(SqQueue Q)
{
	if (Q.rear == Q.front) return true;
	else return false;
}

入队:

//入队
bool EnQueue(SqQueue& Q, int x)
{
	if ((Q.rear+1)%MaxSize==Q.front)//判断队满
		return false;
	Q.data[Q.rear] = x;
	Q.rear = (Q.rear + 1)%MaxSize;//队尾指针加1取模,以循环队列的形式进行存储
}

出队:

//出队
bool DeQueue(SqQueue& Q, int& x)
{
	if (Q.rear == Q.front)//判空
		return false;
	x = Q.data[Q.front];
	Q.front = (Q.front + 1) % MaxSize;//队头后移
	return true;
}

获取队头元素:

//获取队头元素
bool GetHead(SqQueue& Q, int& x)
{
	if (Q.rear == Q.front)//判空
		return false;
	x = Q.data[Q.front];
	return true;
}

判断队满的三种方式:
image.png

image.png

image.png

对于rear和front指针的初始化方式可能会有所不同,由此会有不同的出题方式。

image.png

链式存储

以下为带头结点的链式队列:

结构体:

//结构体
typedef struct LinkNode
{
	int data;
	struct LinkNode* next;
}LinkNode;

typedef struct
{
	LinkNode* front, * rear;//队头队尾指针
}LinkQueue;

初始化:

//初始化
void InitQueue(LinkQueue& Q)
{
	//初始时 front、rear都指向头结点
	Q.front = Q.rear = (LinkNode*)malloc(sizeof(LinkNode));
	Q.front->next = NULL;
}

判空:

//判空
bool IsEmpty(LinkQueue Q)
{
	if (Q.front == Q.rear)
		return true;
	else return false;
}

入队:

//入队
void EnQueue(LinkQueue& Q, int x)
{
	LinkNode* s = (LinkNode*)malloc(sizeof(LinkNode));
	s->data = x;
	s->next = NULL;
	Q.rear->next = s;//新节点插入到rear后面
	Q.rear = s;//修改表尾指针
}

出队:出队时需要进行特判,当出队元素为最后一个结点时,需要修改rear指针。

//出队
bool DeQueue(LinkQueue& Q, int& x)
{
	if (Q.front == Q.rear) return false;//判空
	LinkNode* p = Q.front->next;
	x = p->data;//用变量x返回队头元素
	Q.front->next = p->next;//修改头结点的next指针
	if (Q.rear == p)//此次是最后一个结点出队
		Q.rear = Q.front;//修改rear指针
	free(p);//释放结点空间
	return true;
}

以下是不带头结点的链式队列:

初始化:

//初始化(不带头结点)
void InitQueue2(LinkQueue& Q)
{
	//初始时,front、rear都指向NULL
	Q.front = NULL;
	Q.rear = NULL;
}

判空:

//判空(不带头结点)
bool IsEmpty2(LinkQueue Q)
{
	if (Q.front == NULL) return true;
	else return false;
}

入队:

//入队(不带头结点)
void EnQueue2(LinkQueue& Q, int x)
{
	LinkNode* s = (LinkNode*)malloc(sizeof(LinkNode));
	s->data = x;
	s->next = NULL;
	if (Q.front == NULL)//在空序列中插入第一个元素
	{
		Q.front = s;
		Q.rear = s;
	}
	else
	{
		Q.rear->next = s;
		Q.rear = s;
	}
}

出队:

//出队(不带头结点)
bool DeQueue2(LinkQueue& Q, int& x)
{
	if (Q.front == NULL) return false;
	LinkNode* p = Q.front;//p指向此次出队的结点
	x = p->data;//用变量x返回队头元素
	Q.front = p->next;//修改front指针
	if (Q.rear == p)//此次是最后一个结点出队
	{
		Q.front = NULL;
		Q.rear = NULL;
	}
	free(p);//释放结点
}

双端队列

双端队列是指两端都可以进行入队和出队操作的队列

image.png

image.png

应用

括号匹配

用栈实现括号匹配:

依次扫描所有字符,遇到左括号入栈,遇到右括号则弹出栈顶元素检查是否匹配。

匹配失败情况:

  1. 左括号单身
  2. 右括号单身
  3. 左右括号不匹配

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ux1zXkJz-1686635230730)(null)]

//括号匹配
bool bracketCheck(char* str, int length) {
    SqStack S;
    InitStack(S);//初始化一个栈
    for (int i = 0; i < length; i++) {
        if (str[i] == '(' || str[i] == '[' || str[i] == '{') {
            Push(S, str[i]);//扫描到左括号,入栈
        }
        else {
            if (StackEmpty(S))return false;//扫描到右括号且当前栈空,匹配失败
            char topElem;
            Pop(S, topElem);//栈顶元素出栈进行匹配
            if (str[i] == ')' && topElem != '(')
                return false;
            if (str[i] == ']' && topElem != '[')
                return false;
            if (str[i] == '}' && topElem != '{')
                return false;
        }
    }
    return StackEmpty(S);//最后检查栈,若空匹配成功,非空匹配失败
}

前中后缀表达式

image.png

中缀转后缀(左优先):

当中缀表达式转后缀表达式时,由于运算顺序的不同,可能存在转换为几种不同后缀表达式的情况,此时我们采用左优先原则,保证手算和机算的结果相同。

image.png

中缀转后缀的机算方法:

image.png

后缀表达式的手算方法:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-LQohQ0cw-1686635230708)(null)]

后缀表达式机算:利用栈 先弹出的元素为右操作数

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-hquCC1K8-1686635232135)(null)]

中缀转前缀(右优先):下图以右边的为准

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-GWXSUUrm-1686635230687)(null)]

前缀表达式机算:利用栈 先弹出的元素是左操作数

image.png

中缀表达式的计算(用栈实现)

image.png

栈在递归中的运用

适合用“递归”解决:可以把原始问题转换为属性相同,但规模较小的问题。

image.png

队列的运用

树的层次遍历

图的广度优先遍历

操作系统中FCFS先来先服务的策略

数组

数组的存储

一维数组:

image.png

二维数组(分为按行存储以及按列存储):

image.png

image.png

对称矩阵

若n阶方阵中任意一个元素aij都有aij=aji则该矩阵为对称矩阵。

同样分为行优先以及列优先

image.png

三角矩阵

下三角矩阵:除了主对角线和下三角区,其余的元素都相同。

image.png

上三角矩阵:除了主对角线和上三角区,其余的元素都相同。

image.png

三对角矩阵

又称带状矩阵,当|i-j|>1时,有aij=0(1<=i,j<=n)

由i,j得到k:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-OrvwDtj5-1686635230798)(null)]

由k得到i,j:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-jVAIDTvc-1686635230774)(null)]

由k以及i的表达式可以进一步得到j的表达式

稀疏矩阵

非零元素远远少于矩阵元素的个数

使用三元组存储:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-HFGHxhSc-1686635230753)(null)]

使用十字链表法存储:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-xMbahDSY-1686635230660)(null)]

总结:

image.png
主要参考:王道考研课程
后续会持续更新考研408部分的学习笔记,欢迎关注。
github仓库(含所有相关源码):408数据结构笔记

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

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

相关文章

朋友拿下字节27K的offer,实名羡慕了....

最近有朋友去字节面试&#xff0c;面试前后进行了20天左右&#xff0c;包含4轮电话面试、1轮笔试、1轮主管视频面试、1轮hr视频面试。 据他所说&#xff0c;80%的人都会栽在第一轮面试&#xff0c;要不是他面试前做足准备&#xff0c;估计都坚持不完后面几轮面试。 其实&…

Redux异步解决方案 1. Redux-Thunk中间件

简单介绍一下thunk&#xff0c;这是一个中间件&#xff0c;是解决redux异步问题产生的。我们都知道&#xff0c;在使用redux的时候&#xff0c;通过dispatch一个action 发生到reducer 然后传递给store修改状态 一系列都是同步的&#xff0c;那如果说我dispatch一个action 这个a…

blockchain layer区块链分层

目录 1.layer0 2.layer1 3.layer2 ​4.layer3 1.layer0 第0层的定义目前行业还没有完全一致的理解。多数人认为第0层是 加密数据连接层及其硬件&#xff0c;对应上图下半部分。 也有一些人把跨链或可以创建链的基础设施为作为第0层&#xff0c;他们的代表有: LayerZero、S…

一文讲清后摩尔时代国产高性能并行应用软件生态建设

摘自《后摩尔时代国产高性能并行应用软件生态建设综述》 作者&#xff1a; 龚春叶1&#xff0c;刘杰1&#xff0c;包为民2&#xff0c;潘冬梅1&#xff0c;甘新标1&#xff0c;李胜国1 陈旭光1&#xff0c;肖调杰1&#xff0c;杨博1&#xff0c;王睿伯1 (1.国防科技大学 并…

基于stm32作品设计:多功能氛围灯、手机APP无线控制ws2812,MCU无线升级程序

文章目录 一、作品背景二、功能设计与实现过程三、实现基础功能&#xff08;一&#xff09;、首先是要选材&#xff08;二&#xff09;、原理图设计&#xff08;二&#xff09;、第一版本PCB设计&#xff08;三&#xff09;、焊接PCB板&#xff08;四&#xff09;编写单片机程序…

软件测试基础知识 —— 白盒测试

白盒测试 白盒测试&#xff08;White Box Testing&#xff09;又称结构测试、透明盒测试、逻辑驱动测试或基于代码的测试。白盒测试只测试软件产品的内部结构和处理过程&#xff0c;而不测试软件产品的功能&#xff0c;用于纠正软件系统在描述、表示和规格上的错误&#xff0c…

基于诺亚无人船ROS与Dronekit之间的通信浅析

阿木实验室的诺亚无人船上市已经有一段时间&#xff0c;经过对开发者们的多次调研&#xff0c;我们发现不少开发者都对诺亚无人船的通信实现方式感兴趣&#xff0c;为了帮助大家更好地理解并使用该产品&#xff0c;本期我们将针对诺亚无人船中所使用的linux编程技术以及ROS系统…

2023最新互联网工程师 Java 面试题及答案整理(7 天就能吃透)

现在 Java 面试都只是背答案吗&#xff1f; 不背就通过不了面试&#xff0c;但是现在面试都问原理、问场景&#xff01;Java 面试题就像我们高考时的文言文&#xff0c;包括古诗词&#xff0c;不背是不可能答出来的&#xff01;当然了&#xff0c;除了背&#xff0c;还得理解&…

某球中如何驾驶西锐SR-22小飞机在美国大峡谷中穿行

某球中如何驾驶西锐SR-22小飞机在美国大峡谷中穿行 我已经厌烦了无聊的围绕机场的五边飞行了&#xff0c;想飞一趟跨越乡野的转场飞行了。在我常用的飞软SimplePlanes里面&#xff0c;我已经完成取胜了所有的竞速赛道&#xff0c;我想自己创建一个航路想定&#xff0c;最终选择…

帆软Finereport数据分页,分页查询

目标&#xff1a; 在数据集中一次性获取所有数据后&#xff0c;分页查看&#xff0c;导出时导出的所有数据 如图&#xff1a; 实现步骤&#xff1a; 一、在表格中点击第一列数据集的单元格&#xff0c;添加条件属性&#xff0c; 条件属性内容&#xff1a;&A3 % 5 0 公式解…

【Spring框架学习】了解什么是Spring框架?Spring框架有什么用?创建第一个SpringBoot项目

前言&#xff1a; &#x1f49e;&#x1f49e;今天我们开始学习Spring&#xff0c;这里我们会了解什么是Spring&#xff0c;知道什么是框架&#xff0c;为什么要学Spring框架&#xff0c;框架有什么作用等等。 &#x1f49f;&#x1f49f;前路漫漫&#xff0c;希望大家坚持下去…

pikachu靶场-../../(目录遍历)

目录遍历, 也叫路径遍历, 由于web服务器或者web应用程序对用户输入的文件名称的安全性验证不足而导致的一种安全漏洞&#xff0c;使得攻击者通过利用一些特殊字符就可以绕过服务器的安全限制&#xff0c;访问任意的文件 (可以是web根目录以外的文件&#xff09;&#xff0c;甚至…

客户案例:CACTER邮件安全网关解决餐饮企业邮件安全痛点,有效提升防护!

客户背景 某大型餐饮企业是一家在全国范围内拥有多家连锁店的知名品牌&#xff0c;以优秀的产品和服务质量&#xff0c;严格的质量控制和管理体系&#xff0c;以及开创性的营销策略&#xff0c;赢得了广泛的客户认可和信任。 然而&#xff0c;正因为该企业具有良好的口碑和声誉…

sonar scanner配置

sonar scanner配置 这里记录如何配置sonar scanner扫描C/C项目代码。话不多说&#xff0c;先上官网链接。 文章目录 sonar scanner配置1. 环境1.1 SonarSource Build Wrapper1.2 sonar-scanner 2. 使用2.1 Compilation Database2.2 执行sonar-scanner 3. 注意 1. 环境 对于C…

记录一下CSDN的markdown新功能

新功能目录 CSDN Markdown更新了欢迎使用Markdown编辑器新的改变功能快捷键合理的创建标题&#xff0c;有助于目录的生成如何改变文本的样式插入链接与图片如何插入一段漂亮的代码片生成一个适合你的列表创建一个表格设定内容居中、居左、居右SmartyPants 创建一个自定义列表如…

什么是原型设计?入门最全讲解指南

原型设计在产品开发和用户体验领域扮演着至关重要的角色&#xff0c;产品经理通过画产品原型图&#xff0c;可以让需求可视化&#xff0c;进而快速测试和验证产品可行性&#xff0c;为后续推动产品研发提供坚实可靠的依据。 本文将深入探讨什么是原型设计&#xff0c;原型设计…

【深度学习】0-1 深度学习相关数学概念的简单总结-线性代数

线性代数 标量&#xff08;scalar&#xff09; 标量就是一个单独的数&#xff0c;只具有数值大小&#xff0c;而没有方向&#xff0c;部分有正负之分。一般用小写的变量名称表示&#xff0c;如a、x等。 向量&#xff08;vector&#xff09; 一个向量就是一列数&#xff0c;这…

Kubernetes集群添加新集群节点

Kubernetes集群添加新集群节点 添加worker节点 参考文档https://gitee.com/open-hand/kubeadm-ha/blob/release-1.21/docs/02/%E6%B7%BB%E5%8A%A0%20worker%20%E8%8A%82%E7%82%B9.md 添加工作节点与集群安装时初始化工作节点一样,可以在主节点上执行&#xff0c;也可以在要加…

【ArcGIS Pro二次开发】(39):选择面要素并统计面积(含椭球面积)

写在最前面的话&#xff1a; 这个工具的原型是博主学学GIS做的一个工具 &#xff0c;用于统计当前所选择的面要素的面积&#xff0c;主要是为了解决“亩”的转换&#xff0c;确实是一个很方便好用的工具。大家可移步原贴参观&#xff1a; ArcGIS Pro 加载项&#xff08;5&…

上线新装ap

1.查找ap型号 1.1视频完整版 1.得到这个ap是在5教汇聚的2/0/8口连着的,且这个口是一个互连口 <NYIST-5#J-QY-HuiJu>dis mac-address 9820-449B-10A0<NYIST-5#J-QY-HuiJu>dis lldp neighbor-information list3.得到5教汇聚的2/0/8口所连接的交换机的ip地址为192.…