快接近蓝桥杯省赛了,现在是冲刺阶段,更多的是复习而不再是刷题了,刷过的题多看,多理解考点是什么,记住考过的内容,其实大部分内容都是同一个考点考来考去,只是变换了一个说法而已,所以冲刺阶段,和车神哥一起复习复习基础知识吧!!!加油~
冲刺省赛
比赛提要
考生提醒
关于第十三届蓝桥杯大赛个人赛省赛比赛形式的说明
数据结构基础——队列
队列在比赛中和链表一样也是比较基础的考点。
队列知识点
- 普通队列实现
- 循环队列实现
使用队列的原因
相信大家都学习过数组与链表,对数据的存储方式有了新认识,但是数据的阻滞方式不止一种。今天我们一起来复习一下数据组织方式,常用于特殊题目的考试中。相对于高级一点的算法题中,队列则是一种不可或缺的工具,单独使用次数可能不是很多,但是在其他算法中,不借助队列的逻辑会导致一些算法变得很复杂。
队列的定义
如果说链表和顺序表是对数据的存取位置的组织方式,那么队列就是一种对于存取方式限制的组织方式。换一种方式描述的话就是,队列既可以采用链表来表示,也可以采用数组(线性表)来表示,我们限制的是对于存放数据的存取方式。
下面用图解来解释一下队列的含义。举例一章打饭的图。
顺序存储
链式存储
Tips思考
为什么会存在链式存储方式队列的首位指针与链表头尾刚好相反呢?
简单复习一下Day01中提到的单链表:
目前只用掌握顺序存储的队列即可。
队列实战
通过以上的队列原理介绍,大家也复习的差不多了,下面利用一个小例子对“队列”的操作做一下实战。
题目:
对于输入的解释:
第一行 M 次操作(M<1000)
第二行 到 第M+1行 输入操作
格式: IN name V
OUT V
IN name2 N
OUT N
即 第一个字符串为操作 是IN进入排队和OUT 出队
IN 排队 跟着两个字符串为姓名和权限V或N
OUT 为出队即完成操作,V和N代表那个窗口完成了操作
输出:M次操作后V队列和N队列中姓名,先输出V队列后输出N队列。
样例:
输入:
5
IN xiaoming N
IN Adel V
IN laozhao N
OUT N
IN CLZ V
输出:
Adel
CLZ
laozhao
首先,分析一下本题的思路:
- Step1:创建两个队列,以及两个队列的首位指针
V队列
V队列首指针
V队列尾指针
N队列
N队列首指针
N队列尾指针
- Step2:写入队函数
- 按照队列的定义使用尾指针模拟即可
- 设置 Type 位来表示是哪一个队列
in(Name ,type)
{
Type为V,那么Name进入V队列;
Type为N,那么Name进入N队列;
}
- Step3:写出队函数
- 按照队列的定义使用头指针模拟即可
- 设置 Type 位来表示是哪一个队列
out(type)
{
Type为V,那么V队列出队,如果队列为空则不能出队;
Type为N,那么N队列出队,如果队列为空则不能出队;
}
- Step4:写出获取队头元素的代码,队列我们只关心谁排在第一个
- 按照队列的定义使用头指针模拟即可
- 设置 Type 位来表示是哪一个队列
getHead(type)
{
Type为V,那么取V队列首元素;
Type为N,那么取N队列首元素;
}
- Step5:主函数代码
输入M
循环M次://
输入OP
OP为IN,则输入name和Type
OP为Out,则输入Type
根据执行OP执行in或out操作
若队列V不为空,执行以下操作:
输出队首元素,队首出队
直到为空为止
若队列N不为空,执行以下操作:
输出队首元素,队首出队
直到为空为止
题目解析
队列
队列的逻辑
- 队列:只允许在一端进行插入操作,而另一端进行删除操作的线性表
- 空队列:不含任何数据元素的队列
- 允许插入(也称入队、进队)的一端称为队尾,允许删除(也称出队)的一端称为队头
- 队列的操作特性:先进先出(FIFO),后入后出(LILO)
时间复杂度
- getHead() 查找操作时间复杂度为 O(1)
- in() 入队操作时间复杂度为 O(1)
- out() 出队操作时间复杂度为 O(1)
题目解析(Python)
下面我们尝试动手解决一下 CLZ 银行的问题。
第一步
首先我们要先建存放队列数据结构,我们这里采用顺序表,因为主要存放的数据是名字,也就是常说的字符串,我们可以按照如下方式,进行构建:
global Vhead, Vtail, Nhead, Ntail,Vqueue ,Nqueue
第二步
写入队函数:
- 按照队列的定义使用尾指针模拟即可
- 设置 Type 位来表示是哪一个队列
将上面第一步申明的全局变量包含在入队函数里面。
def inque(name, type):
global Vhead, Vtail, Nhead, Ntail,Vqueue ,Nqueue
if (type == 'V'):
Vqueue.append(name)
Vtail += 1
else:
Nqueue.append(name)
Ntail += 1
第三步
写出队函数:
- 按照队列的定义使用头指针模拟即可
- 设置 Type 位来表示是哪一个队列
def outque(type):
global Vhead, Vtail, Nhead, Ntail,Vqueue ,Nqueue
if (type == 'V'):
if (Vhead == Vtail):
return None
else:
s = getHead(type)
Vhead += 1
return s
else:
if (Nhead == Ntail):
return None
else:
s= getHead(type)
Nhead += 1
return s
第四步
写出获取队头元素的代码,队列我们只需要关心谁排在第一个:
- 按照队列的定义使用头指针模拟即可
- 设置 Type 位来表示是哪一个队列
def getHead(type):
global Vhead, Vtail, Nhead, Ntail,Vqueue ,Nqueue
if (type == 'V'):
# print(Vhead)
return Vqueue[Vhead]
else:
# print(Nhead)
return Nqueue[Nhead]
第五步
主函数代码:
if __name__ == '__main__':
M = 0
M = int(input())
while M > 0:
M -= 1
op = input().split()
# print(op[0])
if op[0] == 'IN':
inque(op[1], op[2])
# print('in')
else:
outque(op[1])
# print('out')
# print("VVVVV",Vqueue)
# print("NNNN",Nqueue)
# print(M)
s = outque('V')
while s!=None:
print(s)
s = outque('V')
s = outque('N')
while s != None:
print(s)
s = outque('N')
完整Python代码(必备模板)
Vqueue = []
Vhead = 0
Vtail = 0
Nqueue = []
Nhead = 0
Ntail = 0
def inque(name, type):
global Vhead, Vtail, Nhead, Ntail,Vqueue ,Nqueue
if (type == 'V'):
Vqueue.append(name)
Vtail += 1
else:
Nqueue.append(name)
Ntail += 1
# print(Vqueue)
def getHead(type):
global Vhead, Vtail, Nhead, Ntail,Vqueue ,Nqueue
if (type == 'V'):
# print(Vhead)
return Vqueue[Vhead]
else:
# print(Nhead)
return Nqueue[Nhead]
def outque(type):
global Vhead, Vtail, Nhead, Ntail,Vqueue ,Nqueue
if (type == 'V'):
if (Vhead == Vtail):
return None
else:
s = getHead(type)
Vhead += 1
return s
else:
if (Nhead == Ntail):
return None
else:
s= getHead(type)
Nhead += 1
return s
if __name__ == '__main__':
M = 0
M = int(input())
while M > 0:
M -= 1
op = input().split()
# print(op[0])
if op[0] == 'IN':
inque(op[1], op[2])
# print('in')
else:
outque(op[1])
# print('out')
# print("VVVVV",Vqueue)
# print("NNNN",Nqueue)
# print(M)
s = outque('V')
while s!=None:
print(s)
s = outque('V')
s = outque('N')
while s != None:
print(s)
s = outque('N')
运行结果
小节(划重点)
以上是带有顺序表结构的队列,相应的还有链表所对应的序列,有兴趣的朋友可以自行查阅资料。在比赛时我们常用 STL 中的 queue 容器,很少会去自己单独定义和使用队列。
关于队列,本次复习主要是复习队列的原理和基本使用,在掌握原理后,无论遇到什么样的队列都可以自己设计出来。
写在最后
车神哥也是第一次参赛——研究生组。不知道难度如何,所以尽力准备就好啦!重要的不是结果,而是那段你孤勇奋战的日子,这样的日子,我相信每个人在人生中都很珍贵。或许是高考,或许是考研,或许是为了仅有的一次升职加薪机会等等。
有梦想,每个人都很了不起!
往期回顾
- 十天冲刺省赛,保送国赛基础知识常考点复习+必背Python代码模板 | Day01 | 数据结构基础之链表
官方刷题练习系统:http://lx.lanqiao.cn/
ღ( ´・ᴗ・` )
❤