python数据结构与算法-04_队列

news2024/11/27 20:36:39

队列和栈

前面讲了线性和链式结构,如果你顺利掌握了,下边的队列和栈就小菜一碟了。因为我们会用前两章讲到的东西来实现队列和栈。
之所以放到一起讲是因为这两个东西很类似,队列是先进先出结构(FIFO, first in first out),
栈是后进先出结构(LIFO, last in first out)。

生活中的数据结构:

  • 队列。没错就是咱平常排队,第一个来的第一个走

本章我们详细讲讲常用的队列

队列 Queue

这里卖个关子,如果你熟悉了上两节讲的内容,这里你会选取哪个数据结构作为队列的底层存储?
还记得第一章讲的如何实现 ADT 吗?我视频了说了三个注意事项:

  • 1.如何选用恰当的数据结构作为存储?
  • 2.选取的数据结构能否满足 ADT 的功能需求
  • 3.实现效率如何?

我们先来看看 list 可以不?对照这个三个需求,看看能否满足:

  • 1.我们选择了 list
  • 2.看起来队列需要从头删除,向尾部增加元素,也就是 list.pop(0) 和 list.append(element)
  • 3.嗯,貌似 list.pop(0) 会导致所有其后所有元素向前移动一个位置,O(n)复杂度。append 平均倒是O(1),但是如果内存不够还要重新分配内存。

你看,使用了 list 的话频繁 pop(0) 是非常低效的。(当然list 实现还有另一种方式就是插入用 list.insert(0, item),删除用list.pop())

脑子再转转, 我们第二章实现了 链表 LinkedList,看看能否满足要求:

  • 1.这里选择 LinkedList
  • 2.删除头元素 LinkedList.popleft(),追加 append(element)。都可以满足
  • 3.哇欧,这两个操作都是 O(1) 的,完美。

好, 就用 LinkedList 了,我们开始实现,具体看视频。这次实现我们还将演示自定义异常和测试异常。

用数组实现队列

难道用数组就不能实现队列了吗?其实还是可以的。只不过数组是预先分配固定内存的,所以如果你知道了队列的最大长度,也是
可以用数组来实现的。

想象一下,队列就俩操作,进进出出,一进一出,pop 和 push 操作。
似乎只要两个下标 head, tail 就可以了。 当我们 push 的时候赋值并且前移 head,pop 的时候前移 tail 就可以了。你可以在纸上
模拟下试试。列队的长度就是 head-pop,这个长度必须不能大于初始化的最大程度。

如果 head 先到了数组末尾咋办?重头来呗,只要我们保证 tail 不会超过 head 就行。

head = 0,1,2,3,4 … 0,1,2,3,4 …

重头再来,循环往复,仿佛一个轮回。。。。
怎么重头来呢?看上边数组的规律你如果还想不起来用取模,估计小学数学是体育老师教的。

maxsize = 5
for i in range(100):
    print(i % maxsize)

在这里插入图片描述

我们来实现一个空间有限的循环队列。ArrayQueue,它的实现很简单,但是缺点是需要预先知道队列的长度来分配内存。

双端队列 Double ended Queue

看了视频相信你已经会实现队列了,你可能还听过双端队列。上边讲到的队列 队头出,尾尾进,我们如果想头部和尾巴都能进能出呢?
这就是双端队列了,如果你用过 collections.deque 模块,就是这个东西。他能高效在两头操作。

假如让你实现你能想起来嘛?
似乎我们需要一个能 append() appendleft() popleft() pop() 都是 O(1) 的数据结构。

上边我们实现 队列的 LinkedList 可以吗?貌似就差一个 pop() 最后边的元素无法实现了。
对,我们还有双端链表。它有这几个方法:

  • append
  • appendleft
  • headnode()
  • tailnode()
  • remove(node) # O(1)

啊哈,似乎删除头尾都可以啦,而且都是 O(1) 的,完美。
交给你一个艰巨的任务,实现双端队列 Deque() ADT。你可以参考前几章的任何代码,挑战一下这个任务,别忘记写单元测试呦。当然如果没想出来也没关系,后边我们实现栈的时候还会用到它,那里我们会实现这个代码。

源码

# -*- coding: utf-8 -*-


# NOTE: 从 array_and_list 第一章拷贝的代码
class Array(object):

    def __init__(self, size=32):
        self._size = size
        self._items = [None] * size

    def __getitem__(self, index):
        return self._items[index]

    def __setitem__(self, index, value):
        self._items[index] = value

    def __len__(self):
        return self._size

    def clear(self, value=None):
        for i in range(len(self._items)):
            self._items[i] = value

    def __iter__(self):
        for item in self._items:
            yield item


class FullError(Exception):
    pass


class ArrayQueue(object):
    def __init__(self, maxsize):
        self.maxsize = maxsize
        self.array = Array(maxsize)
        self.head = 0
        self.tail = 0

    def push(self, value):
        if len(self) >= self.maxsize:
            raise FullError('queue full')
        self.array[self.head % self.maxsize] = value
        self.head += 1

    def pop(self):
        value = self.array[self.tail % self.maxsize]
        self.tail += 1
        return value

    def __len__(self):
        return self.head - self.tail


def test_queue():
    import pytest    # pip install pytest
    size = 5
    q = ArrayQueue(size)
    for i in range(size):
        q.push(i)

    with pytest.raises(FullError) as excinfo:   # 我们来测试是否真的抛出了异常
        q.push(size)
    assert 'full' in str(excinfo.value)

    assert len(q) == 5

    assert q.pop() == 0
    assert q.pop() == 1

    q.push(5)

    assert len(q) == 4

    assert q.pop() == 2
    assert q.pop() == 3
    assert q.pop() == 4
    assert q.pop() == 5

    assert len(q) == 0

思考题

  • 你能用 python 的 deque 来实现 queue ADT 吗?
  • 哪些经典算法里用到了队列呢?

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

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

相关文章

fastDFS文件存储获取tracker连接报空指针异常

一、问题 异常报错: 2023-11-14 15:12:58.530 ERROR 13888 --- [nio-9008-exec-2] com.changgou.file.util.FastDFSClient : Exception when uploadind the file:1.jpg java.lang.NullPointerException: null at org.csource.fastdfs.TrackerClient.getC…

Ansible 企业实战详解

一、ansible简介1. ansible是什么2.ansible的特点ansible的架构图 二、ansible 任务执行1、ansible 任务执行模式2、ansible 执行流程3、ansible 命令执行过程 二 .Ansible安装部署1.yum安装2.ansible 程序结构3、ansible配置文件查找顺序4、ansible配置文件5.ansible自动化配置…

原神助手 一款支持祈愿分析、查看便签状态和获取游戏详细数据的开源工具。

原神助手 「原神助手」支持祈愿分析、查看便签状态和获取游戏详细数据等。 如何获取祈愿链接 如果你是在 Windows 平台上游玩原神并且当前使用的电脑上安装了原神,那么你可以: 打开原神,进入祈愿页面,点击历史记录,…

软件测试自学指南,十年阿里测试工程师的建议

通过技能提升,入行IT可以的,但得先积累足够的经验,才能拿高薪,有个成长的过程。 软件测试岗介绍 软件测试岗位主要负责系统的测试工作,属于IT项目中的质量管理(QA)模块。 这个岗位分为两种类…

Jordan 引理

See https://wuli.wiki/online/JdLem.html#ex_JdLem_1

如何禁止谷歌浏览器Google Chrome自动更新?

Windows系统: 按下Win R键,打开“运行”对话框;在对话框输入“services.msc”,并按下Enter键或者“确定”按钮。 在服务列表中找到“Google 更新服务”。 右键单击该服务,选择“属性”,将“启动类型”更改…

Leetcode刷题详解——不同路径 III

1. 题目链接:980. 不同路径 III 2. 题目描述: 在二维网格 grid 上,有 4 种类型的方格: 1 表示起始方格。且只有一个起始方格。2 表示结束方格,且只有一个结束方格。0 表示我们可以走过的空方格。-1 表示我们无法跨越的…

提高软件测试覆盖率的5个重点

软件测试覆盖率是软件测试中的一个重要指标,它有利于保障软件质量、提高软件可靠性和可维护性。软件测试覆盖率能够发现并修复代码缺陷,确保代码的正确性,提高软件的稳定性,降低成本和风险。 因此进一步提高软件测试覆盖率对于软件…

weblogic漏洞修复打补丁

序号漏洞名称加固建议1Oracle Fusion Middleware Oracle WebLogic Server组件安全漏洞(CVE-2017-10352)http://www.oracle.com/technetwork/security-advisory/cpuoct2017-3236626.html2Oracle Fusion Middleware和Oracle WebLogic Server 输入验证错误漏洞(CVE-2021-35617)htt…

Python武器库开发-flask篇之flask框架的安装(二十一)

Flask介绍 Flask是一个基于Python开发并且依赖jinja2模板和Werkzeug WSGI服务的一个微型框架,对于Werkzeug本质是Socket服务端,其用于接收http请求并对请求进行预处理,然后触发Flask框架,开发人员基于Flask框架提供的功能对请求进…

【科研新手指南2】「NLP+网安」相关顶级会议期刊 投稿注意事项+会议等级+DDL+提交格式

「NLP网安」相关顶级会议&期刊投稿注意事项 写在最前面一、会议ACL (The Annual Meeting of the Association for Computational Linguistics)IH&MMSec (The ACM Workshop on Information Hiding, Multimedia and Security)CCS (The ACM Conference on Computer and Co…

识别代理IP:保障网络安全的重要一环

在互联网的世界中,代理服务器被广泛用于隐藏用户真实IP地址,带来了一些挑战,特别是在网络安全和欺诈检测方面。本文将探讨如何识别代理IP,以确保网络的安全性和可靠性。 1. 代理IP的背景与用途 代理服务器是位于用户和目标服务器…

各路大神献出自定义GPTs,24小时Top名单

没有 GPTs 做不到的,只有你想不到的。 11 月 10 日凌晨, OpenAI 上线 GPTs,所有的 ChatGPT Plus 订阅用户都可以自己定制 GPT,无需任何编码知识,在聊天过程中就构建好了。 发布当天,OpenAI CEO 山姆・奥特曼…

安卓调用手机邮箱应用发送邮件

先来看看实现效果&#xff1a; 也不过多介绍了&#xff0c;直接上代码&#xff1a; private void openMail() {Uri uri Uri.parse("mailto:" "");List<ApplicationInfo> applicationInfoList getPackageManager().getInstalledApplications(Packa…

XMind 2023 mac/win:引领思维导图革命,让思维更直观、更高效!

XMind是一款引领思维导图的革命性软件&#xff0c;以其强大的功能和高效的操作体验&#xff0c;赢得了全球用户的广泛喜爱。作为一款思维导图软件&#xff0c;XMind将复杂的思维过程和想法以直观、清晰的方式呈现出来&#xff0c;让用户能够更好地理解、组织和表达自己的思想。…

Git推送本地代码到远程仓库

Git推送本地代码到远程仓库 1、首先需要安装Git&#xff0c;如果已经安装&#xff0c;请跳过。下载地址&#xff1a;https://git-for-windows.github.io/ 2、安装好git服务器后。首先找到你项目的文件夹&#xff0c;比如项目名称为Item&#xff0c;进入到这个文件夹&#xff0…

5 个基本步骤,学会创建自己的CRM流程

客户关系管理 (CRM) 系统是必备的客户数据库工具&#xff0c;用于跟踪潜在客户、现有客户、接触点等。使用可靠的技术来跟踪所有客户数据固然重要&#xff0c;但为该技术制定的流程更为关键。因这是用来管理客户和整个客户生命周期的策略。 什么是CRM流程&#xff1f; CRM流程…

SpringBoot从零到一项目实战落地博客系统(附源码!!!)

1.项目内容 1.1.页面展示 1.2.博客分类 1.3.面试辅导 1.4.私教带徒 1.5.文章编辑 1.6.后台管理 2.项目架构及技术描述 2.1.本项目用到的技术和框架 项目构建&#xff1a;Mavenweb框架&#xff1a;Springboot数据库ORM&#xff1a;Mybatis数据库连接池&#xff1a; HikariCP分…

MySQL锁机制详解

概述 锁是计算机协调多个进程或线程并发访问某一资源的机制。 在数据库中&#xff0c;除了传统的计算资源&#xff08;如CPU、RAM、I/O等&#xff09;的争用以外&#xff0c;数据也是一种供需要用户共享的资源。如何保证数据并发访问的一致性、有效性是所有数据库必须解决的一…

设备管理平台能做什么?企业如何做好设备维护管理工作?

在当今高度数字化的时代&#xff0c;企业运营离不开各种设备的支持。如何确保这些设备高效运转&#xff0c;降低故障率&#xff0c;成为了企业运营的关键问题。为此&#xff0c;设备管理平台应运而生&#xff0c;它借助数字化、移动互联网等技术&#xff0c;为企业提供全方位的…