基础数据结构——队列和栈

news2024/12/24 21:20:37

目录

一、队列

1、循环队列

2、Python队列的三种实现方式

3、例题——队列操作

4、优先队列

(1)基本操作

(2)例题(lanqiaoOJ题号1228)

二、栈

1、用 list 实现栈

2、用 collections.deque 实现栈

3、用 queue.LifoQueue 实现栈

4、例题(lanqiaoOJ题号2117)

(1)暴力法

(2)栈


 

一、队列

【队列】

先进先出

只能从队头离开队列

只能从队尾进入队列

【缺点】

队列的查找慢,从头到尾一个个查找

1、循环队列

  • 用一组连续的存储单元依次存放队列元素
  • head 指示队列头元素
  • rear 指向尾元素
  • 当 head 和 rear 走到底时,下一步回到开始的位置,从而在这组连续空间内循环。

2、Python队列的三种实现方式

【实现方式】

① 用 queue 实现队列操作。有 q.size()、q.empty()、q.put()、q.get() 等功能。

② 列表 list 就是一个普通队列。

③ collections.deque。 deque最快,快30倍。

Queue常用的方法:

① qsize()                                        获取队列的元素个数。

② put(item [,block[, timeout]])        往queue中放一个item

③ get(item [,block[, timeout]])        从queue中取出一个item,并在队列中删除的这个item

3、例题——队列操作

用 queue 实现队列:

from queue import *
q=Queue()
n=eval(input())
for i in range(n):
    s=list(map(int,input().split()))
    if s[0]==1:
        q.put(s[1])
    elif s[0]==2:
        if not q.empty():
            a=q.get()
            print(a)
        else:
            print('no')
            break
    elif s[0]==3:
        print(q.qsize())

7
1 19
1 56
2
19
3
1
2
56
3
0
2
no
>>>

用 list 实现队列:

n=eval(input())
q=[]
for i in range(n):
    s=list(map(int,input().split()))
    if s[0]==1:
        q.append(s[1])
    elif s[0]==2:
        if len(q)>0:
            q.reverse()
            a=q.pop()
            print(a)
            q.reverse()
        else:
            print('no')
            break
    elif s[0]==3:
        print(len(q))

用 deque 实现队列:

from collections import *
n=eval(input())
q=deque()
for i in range(n):
    s=list(map(int,input().split()))
    if s[0]==1:
        q.append(s[1])
    elif s[0]==2:
        if len(q)>0:
            a=q.popleft()
            print(a)
        else:
            print('no')
            break
    elif s[0]==3:
        print(len(q))

4、优先队列

  • 很多算法需要用到一种特殊的队列:优先队列。它的特点是:最优数据始终位于队列头部。
  • 优先队列的效率很高:新数据插入队列生成新的最优队头,计算复杂度是 O(logn);
  • 弹出最优的队头后在队列中计算出新的最优队头,计算复杂度也是 O(logn)。

(1)基本操作

PriorityQueue 的基本操作:

pq = queue.PriorityQueue()

pq.put ([priority, value])        #进队列

pq.get ()        #取出队首。

put 函数的第一个参数 priority 表示数据的优先级,第二个参数 value 是值,值越小优先级越高。队首总是最小值。

import queue
pq = queue.PriorityQueue()
pq.put([1,'abc'])
pq.put([7,998])
pq.put([5,True])
while not pq.empty():
    print(pq.get(),end=' ')

(2)例题(lanqiaoOJ题号1228)

【题目描述】

小明买了 n 件白色的衣服,他希望对这些衣服进行染色,每次染色时,他会将某种颜色的所有衣服寄去染色厂,第 i 件衣服的邮费为 ai 元,染色厂会按照小明的要求将其中一部分衣服染成同一种任意的颜色,之后将衣服寄给小明,请问小明要将 n 件衣服染成不同颜色的最小代价是多少?

【输入描述】

第一行为一个整数 n,表示衣服的数量。第二行包括 n 个整数 a1, a2, ..., an 表示第 i 件衣服的邮费为 ai 元。 (1 <= n <= 105,1<=ai<=109)

【输出描述】

输出一个整数表示小明所要花费的最小代价。

【输入样例】

5

4 5 3 3 7

【输出样例】

50

import queue
pq = queue.PriorityQueue()
n=int(input())
a=list(map(int,input().split()))

for i in range(len(a)):
    pq.put(a[i])

sum=0
while pq.qsize()>1:
    t = pq.get()+ pq.get()
    sum += t
    pq.put(t)

print(sum)

5
4 5 3 3 7
50
>>>

二、栈

【栈(stack)】

  • “先进后出”
  • 只有唯一的一个出入口,既从这个口进入,又从这个口出来,这是和队列最大的区别。
  • 队列有两个口,一个入口和一个出口。

1、用 list 实现栈

st=[]
st.append('hello')  # 送入栈,功能是 push()
st.append('world')
st.append(453)
print(st)
print(len(st))      # 栈的长度
print(st[len(st)-1])    # 打印栈顶,功能是top()
print(st[-1])       # 打印栈顶,功能是top()
print(st.pop())     # 弹出栈顶
print(st.pop())     # 弹出栈顶
print(st.pop())     # 弹出栈顶
print(st)
if st:
    print("Not Empty")  # 是否为空,功能是empty()
else:
    print("Empty")      # Empty

2、用 collections.deque 实现栈

from collections import deque
st=deque()
st.append('hello')  # 送入栈,功能是 push()
st.append('world')
st.append(453)
print(st)
print(len(st))      # 栈的长度
print(st[len(st)-1])    # 打印栈顶,功能是top()
print(st[-1])       # 打印栈顶,功能是top()
print(st.pop())     # 弹出栈顶
print(st.pop())     # 弹出栈顶
print(st.pop())     # 弹出栈顶
print(st)           # deque([])
if st:
    print("Not Empty")  # 是否为空,功能是empty()
else:
    print("Empty")      # Empty

3、用 queue.LifoQueue 实现栈

Lifo:last in first out,后进先出,就是栈

from queue import LifoQueue
st=LifoQueue(maxsize=100)
st.put('hello')
st.put('world')
st.put(453)
print(st.qsize())   #栈的长度 3
print(st.get())     #弹出栈顶 453
print(st.get())     #弹出栈顶 world
print(st.get())     #弹出栈顶 hello
print(st.empty())     #是否为空 True

4、例题(lanqiaoOJ题号2117)

【题目描述】

小明砍竹子,他面前有 n 棵竹子排成一排,一开始第 i 棵竹子的高度为 hi。他觉得一棵一棵砍太慢了,决定使用魔法来砍竹子。魔法可以对连续的一段相同高度的竹子使用,假设这一段竹子的高度为H,那么使用一次魔法可以把这一段竹子的高度都变为?,其中?表示对x向下取整。小明想知道他最少使用多少次魔法可以让所有的竹子的高度都变为 1。

【输入描述】

第一行为一个正整数 n,表示竹子的棵数。第二行共 n 个空格分开的正整数 hi,表示每棵竹子的高度。

【输出描述】

一个整数表示答案。

【输入样例】

6

2 1 4 2 6 7

【输出样例】

5

(1)暴力法

  • 从第一棵竹子开始,从头到尾,找到相同高度的竹子,砍掉这一段竹子。循环做这个操作,直到所有高度都变为 1。
  • 复杂度:从左到右遍历一次 O(n),可能遍历很多轮,总复杂度大于 O(n^2)。只能通过 20% 的测试。
from math import *
n=int(input())
a=list(map(int,input().split()))
ans=0

while True:
    idx=0
    for i in range(n):
        if a[i]>a[idx]:
            idx=i
    if a[idx]==1:
        break   # 全部高度都是1
    val=a[idx]
    for i in range(idx,n):
        if a[i]!=val:
            break
        a[i]=floor(sqrt(floor(a[i]/2)+1))   # floor() 向下取整
    ans+=1
print(ans)

(2)栈

  • 首先计算最多砍多少刀,计算每棵竹子砍到 1 需要多少刀,所有竹子砍数相加得到一个总数,记为ans;
  • 记录每棵竹子每次被砍后的新高度;
  • 比较任意两个相邻的竹子,它们是否有相同的高度,如果有相同的高度,这两棵竹子接下来可以一起砍,从而少砍一刀,ans减一;
  • 比较结束后,ans 就是答案。
from math import *
f=[[0]*10 for _ in range(200010)]
stk=[0]*10

n=int(input())
a=list(map(int,input().split()))
ans=0

for i in range(n):
    x=a[i]
    top=0
    while x>1:
        top+=1
        stk[top]=x
        x=floor(sqrt(floor(x/2)+1))
    ans+=top
    k=top
    j=0
    while k>0:
        f[i][j]=stk[k]
        k-=1
        j+=1
for j in range(10):
    for i in range(1,n):
        if f[i][j]>0 and f[i][j]==f[i-1][j]:
            ans-=1
print(ans)
  • f[ ][ ] 记录每棵竹子被砍后的高度,f[ i ][ j ] 记录第 i 棵竹子被砍后的高度,f [ i ][ 0 ] 是砍最后一刀后的高度,f[ i ][ top ]是第一次被砍后的高度。
  • 用手写栈 stk[ ] 记录砍每刀后的高度,然后赋值给 f[ i ][ ]。比较任意两棵相邻竹子的高度,如果有某个高度相等,可以一起砍,从而少砍一刀。
  • 代码的复杂度:两个 for 循环计算 M×n = 10×n 次,是 O(n) 的。总复杂度为 O(n)。

以上,基础数据结构——队列和栈

祝好

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

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

相关文章

【知识图谱导论-浙大】第一章:知识图谱概论

背景 2022年&#xff0c;随着在自然语言处理方向的深入&#xff0c;我逐渐开始对知识图谱在问答、搜索、推荐等领域的应用产生浓厚的兴趣。自己也通过书籍、博文、论文等对知识图谱有所了解&#xff0c;也通过中文开放知识图谱对中文知识图谱在各领域的发展有了深刻的认识。知…

将非负整数num转换为对应的英文表达(C++实现)—— 力扣第273号题的加强。

【问题描述】 将非负整数num转换为对应的英文表达式。 (样例1) 输入&#xff1a;25 输出&#xff1a;Twenty Five (样例2) 输入&#xff1a;12,315 输出&#xff1a;Twelve Thousand Three Hundred (and) Fifteen 备注&#xff1a;and可省略 另备注&#xff1a;偶然发…

(八)devops持续集成开发——jenkins流水线发布一个docker版的后端maven项目

前言 本节内容我们使用jenkins的流水化工具发布一个后端docker项目&#xff0c;实现后端项目的容器化部署。在开始本节内容之前&#xff0c;我们需要在生产环境安装好docker环境并且能够联网下载镜像。通过jenkins的流水化工具&#xff0c;实现代码拉取&#xff0c;maven打包编…

【java篇】反射机制简单理解

学到JDBC后&#xff0c;使用到反射机制&#xff0c;所以回顾反射机制相关知识点&#xff1b; 文章目录 文章目录 什么是反射机制&#xff1f; 如何理解反射呢&#xff1f; 总结 一、Java反射机制是什么&#xff1f; 二、Java反射机制中获取Class的三种方式及区别&#xff1f; 三…

【目标检测】EfficientDet

1、论文 题目&#xff1a;《EfficientDet: Scalable and Efficient Object Detection》 论文地址&#xff1a; https://arxiv.org/pdf/1911.09070.pdf 代码地址&#xff1a; https://github.com/bubbliiiing/efficientdet-pytorch 2、摘要 Google Brain团队在CVPR 2020上提出…

Liunx 对函数库的理解

一、前言 我们的C程序中&#xff0c;并没有定义“printf”的函数实现,且在预编译中包含的“stdio.h”中也只有该函数的声明,而没有定义函数的实现,那么,是在哪里实“printf”函数的呢?最后的答案是:系统把这些函数实现都被做到名为 libc.so.6 的库文件中去了,在没有特别指定时…

PCB入门学习— CHIP类PCB封装的创建

目录 2.12 原理图PCB封装完整性的检查 3.1 CHIP类PCB封装的创建 学习目录 2.12 原理图PCB封装完整性的检查 然后点接受变更。 www.digikey.com搜索规格的网站。 3.1 CHIP类PCB封装的创建 放焊盘——确定大小——画丝印——确定原点EFC。 创建一个PCB元件库&#xff0c;Ct…

React(coderwhy)- 07(路由)

认识React-Router 认识前端路由 ◼ 路由其实是网络工程中的一个术语&#xff1a;  在架构一个网络时&#xff0c;非常重要的两个设备就是路由器和交换机。  当然&#xff0c;目前在我们生活中路由器也是越来越被大家所熟知&#xff0c;因为我们生活中都会用到路由器&#x…

红黑树:比AVL抽象、自由的、更广泛的近似平衡树

RBT与AVL树的比较 AVL&#xff1a;高度要求差不超过1红黑树&#xff1a;RBT要求最长路径不超过短路径的2倍&#xff0c;不需要像AVL一样太平衡&#xff0c;稍微自由&#xff0c;所以旋转较少。 AVL和RBT树性能比较&#xff1a; 插入同样的数据&#xff0c;AVL树旋转更多&…

本地生活配送行业黑马,带你一键读懂闪飞侠

电商的黄金十年已经过去&#xff0c;本地生活的黄金市场才刚刚开启&#xff0c;本地生活市场的增长对同城配送的影响得有多大&#xff1f;2020年的新冠疫情&#xff0c;爆发了同城即时配送的投资新机遇&#xff01;即时配送用户已超5亿。而随着即时配送行业的广泛应用&#xff…

【 Vue3 + Vite + setup语法糖 + Pinia + VueRouter + Element Plus 第三篇】(持续更新中)

在第二篇我们主要学习了路径别名&#xff0c;配置.env环境变量&#xff0c;封装axios请求&#xff0c;以及使用api获取数据后渲染 Element Plus表格 本期需要掌握的知识如下: 封装列表模糊查询组件实现新增 编辑 删除 模糊查询 重置 功能实现表单校验功能实现组件间传值 下期…

Compose跨平台第一弹:体验Compose for Desktop

前言 Compose是Android官方提供的声明式UI开发框架&#xff0c;而Compose Multiplatform是由JetBrains 维护的&#xff0c;对于Android开发来说&#xff0c;个人认为学习Jetpack Compose是必须的&#xff0c;因为它会成为Android主流的开发模式&#xff0c;而compose-jb作为一…

TikTok三大流行趋势 钛动带你看懂TikTok

武汉瑞卡迪电子商务有限公司&#xff1a;近日,TikTok for Business发布了《Whats Next 2023 TikTok 全球流行趋势报告》,就2023年TikTok三大趋势主题进行了介绍。 钛动科技作为TikTok官方授权代理商,是TikTok生态服务最齐全的出海服务商,凭借出色的技术与服务能力,钛动斩获了T…

论 G1 收集器的架构和如何做到回收时间用户设定

目录G1 概念JVM的内存分代假设让用户设置应用的暂停时间G1 概念 G1其实是Garbage First的意思&#xff0c;它不是垃圾优先的意思&#xff0c;而是优先处理那些垃圾多的内存块的意思。 在大的理念上&#xff0c;它还是遵循JVM的内存分代假设。 JVM的内存分代假设 JVM的内存分代…

https如何加密解密?

背景 我们知道&#xff0c;https&#xff0c;在网络传输中&#xff0c;加密。具体来说是数据加密。//客户端和服务器&#xff0c;写数据的时候&#xff0c;都会加密。即1.客户端——》服务器 2.服务器——》客户端。 如何加密 解密&#xff1f; 加密解密 想要加密和解密&am…

【Mysql篇】数据库事务

目录 数据库事务数据库事务介绍 JDBC事务处理 事务的ACID属性 数据库的并发问题 数据库提供的4种事务隔离级别&#xff1a; 在MySql中设置隔离级别 数据库事务数据库事务介绍 事务&#xff1a;一组逻辑操作单元,使数据从一种状态变换到另一种状态。 事务处理&#xff08;…

Day1. Spring

1 课程描述IoC基础容器&#xff0c;主要涉及Bean对象的管理。AOP面向切面编程&#xff0c;主要涉及切面配置&#xff0c;声明式事务控制Spring整合Web环境。Web层解决方案-SpringMVC.1.1 IoC、DI和AOP思想的提出由于传统的JavaWeb出现的问题&#xff1a;问题1&#xff1a;层与层…

【问题记录】Process finished with exit code -1073740791 (0xC0000409) 注:LSTM股票预测案例中

目录 1. 问题来源2. 问题解决1. 问题来源 在跑一段 LSTM&神经网络 股票预测的代码时,遇到了下述报错,报错提示为: Process finished with exit code -1073740791 (0xC0000409) 报错截图为: 下面是整个报错的内容,这里我也截取下来了: H:\Python学习专用\深度学习\LS…

ECMAScript基础入门

JavaScript&#xff08;浏览器端&#xff09;ECMAScript&#xff08;语法API&#xff09;DOMBOM es6开始let代替var声明变量&#xff08;初始化后可重新赋值&#xff09;&#xff0c;而const声明常量&#xff08;初始化后不可重新赋值&#xff0c;否则会报错&#xff09; con…

Java调用百度OCR接口实现文字识别

博主在项目开发中需要完成一个文字识别功能&#xff0c;由于之前有过使用百度云平台接口进行身份证识别的经历&#xff0c;因此这次也是自然而然的再次选择了百度AI平台&#xff0c;首先需要开通百度通用文字识别功能。 然后我们需要创建一个应用&#xff1a; 然后我们就可以…