数据结构之队列(python)

news2024/10/25 3:28:21

华子目录

  • 1.队列存储结构
    • 1.1队列基本介绍
    • 1.2队列的实现方式
  • 2.顺序队列
    • 2.1顺序队列的介绍
    • 2.2顺序队列的简单实现
    • 2.3代码实现
  • 3.链式队列和基本操作
    • 3.1链式队列数据入队
    • 3.2链式队列数据出队
    • 3.3队列的链式表示和实现

1.队列存储结构

1.1队列基本介绍

  • 队列两端都"开口",要求数据只能从一端进,从另一端出,如图 1 所示:

在这里插入图片描述

  • 进数据一端为 “队尾”,出数据一端为 “队头”,数据元素进队列的过程称为 “入队”,出队列的过程称为 “出队”。
  • 队列中数据的进出要遵循 “先进先出” 的原则,即最先进队列数据元素,同样要最先出队列
  • 图1中的队列来说,从数据队列中的存储状态可以分析出元素1 最先进队,其次元素2最后元素3。此时如果将元素3出队,根据队列 “先进先出” 的特点,元素1先出队列元素2 再出队列,最后才轮到元素3 出队列。
  • 因此,数据从一端进,从另一端出,且遵循 “先进先出” 原则的线性存储结构就是队列
  • 实际生活中,队列应用随处可见,比如排队买XXX医院的挂号系统等,采用的都是队列结构

1.2队列的实现方式

队列存储结构的实现有以下两种方式:

  • 顺序队列:在顺序表的基础上实现的队列结构
  • 链队列:在链表的基础上实现的队列结构

2.顺序队列

2.1顺序队列的介绍

顺序队列,即采用顺序表模拟实现的队列结构

  • 我们知道,队列具有以下两个特点:
    • 数据从队列的一端进,另一端出
    • 数据的入队出队遵循"先进先出"的原则

因此,只要使用顺序表按以上两个要求操作数据,即可实现顺序队列。首先来学习一种最简单实现方法

2.2顺序队列的简单实现

  • 由于顺序队列底层使用的是数组,因此需预先申请一块足够大内存空间初始化顺序队列。除此之外,为了满足顺序队列中数据从队尾进队头出先进先出的要求,我们还需要定义两个指针toprear)分别用于指向顺序队列中的队头元素队尾元素,如图 1 所示:

在这里插入图片描述

  • 由于顺序队列初始状态没有存储任何元素,因此 top指针rear指针重合,且由于顺序队列底层实现靠的是数组,因此 toprear 实际上是两个变量,它的分别是队头元素队尾元素所在数组位置下标
  • 图1 的基础上,当有数据元素队列时,对应的实现操作是将其存储在指针rear 指向的数组位置,然后 rear+1;当需要队头元素出队时,仅需做 top+1 操作。

例如,在图1 基础上将 {1,2,3,4}顺序队列存储的实现操作如图2 所示:

在这里插入图片描述
图2 基础上,顺序队列中数据出队列实现过程图3所示:
在这里插入图片描述

2.3代码实现

实现基本功能:

  • 初始化队列
  • 判断队列是否为
  • 返回队头元素
  • 返回队列长度
  • 入队 : 添加元素队尾
  • 出队 : 删除队头元素
  • 遍历队列
  • 清空队列
# 本次顺序队列定义及相关函数较多使用python自身所带的列表和函数
class Queue:
    #队列初始化
    def __init__(self):
        self.items = []

    #判断队列是否为空
    def is_empty(self):
        return self.items == []

    #元素入队
    def enter_queue(self, item):
        self.items.insert(0, item)

    #队首元素出队
    def go_queue(self):
        return self.items.pop()

    #返回队列长度
    def size(self):
        return len(self.items)

    #清空队列
    def clear(self):
        self.items.clear()

    #获取队首元素
    def getTop(self):
        return self.items[self.size()-1]

    #遍历队列
    def display(self):
        return self.items



if __name__ == '__main__':
    q = Queue()
    print("---------------------")
    print("初始化后的队列:", q)
    print("---------------------")
    print("当前队列是否为空:", q.is_empty())
    print("---------------------")
    print("入队前队内元素为:", q.display())
    q.enter_queue(5)
    q.enter_queue(10)
    q.enter_queue(11)
    print("入队后队内元素为:", q.display())
    print("---------------------")
    print("当前队首元素为:", q.getTop())
    print("---------------------")
    print("出队前队内元素为:", q.display())
    q.go_queue()
    print("出队后队内元素为:", q.display())
    print("---------------------")
    print("当前队列长度为:", q.size())
    print("---------------------")
    print("清空前队内元素为:", q.display())
    q.clear()
    print("清空后队内元素为:", q.display())
---------------------
初始化后的队列: <__main__.Queue object at 0x0000017D90EB8460>
---------------------
当前队列是否为空: True
---------------------
入队前队内元素为: []
入队后队内元素为: [11, 10, 5]
---------------------
当前队首元素为: 5
---------------------
出队前队内元素为: [11, 10, 5]
出队后队内元素为: [11, 10]
---------------------
当前队列长度为: 2
---------------------
清空前队内元素为: [11, 10]
清空后队内元素为: []

3.链式队列和基本操作

  • 使用链表实现的队列存储结构
  • 需要创建两个指针(命名为 toprear)分别指向链表中队列的队头元素队尾元素,如图 1 所示:

在这里插入图片描述

  • 图1 所示为链式队列初始状态,此时队列中没有存储任何数据元素,因此 toprear 指针都同时指向头节点
  • 在创建链式队列时,强烈建议初学者创建一个带有头节点链表,这样实现链式队列更简单

3.1链式队列数据入队

链队队列中,当有新的数据元素入队,只需进行以下 3步操作:

  • 该数据元素用节点包裹,例如新节点名称为 elem
  • rear指针指向的节点建立逻辑关系,即执行 rear->next=elem
  • 最后移动 rear指针指向该新节点,即 rear=elem

由此,新节点就入队成功了。

例如,在图1 的基础上,我们依次将 {1,2,3} 依次入队各个数据元素入队的过程如图2 所示:
在这里插入图片描述

3.2链式队列数据出队

链式队列中,有数据元素需要出队时,按照 “先进先出” 的原则,只需将存储该数据的节点以及它之前入队的元素节点按照原则依次出队即可。这里,我们先学习如何将队头元素出队

链式队列队头元素出队,需要做以下 3 步操作:

  • 通过 top 指针直接找到队头节点,创建一个新指针p 指向此即将出队的节点
  • p 节点(即要出队队头节点)从链表中摘除
  • 释放节点p回收其所占的内存空间

例如,在图 2)的基础上,我们将元素 12 出队,则操作过程如图 3 所示:

在这里插入图片描述

3.3队列的链式表示和实现

实现基本功能

  • 初始化队列
  • 判断队列是否为
  • 返回队头元素
  • 返回队列的长度
  • 入队: 添加元素到队尾
  • 出队: 删除队头元素
  • 遍历队列
  • 清空队列
'''
1. 队列特点:先进先出,队尾入队操作,队头出队操作
2. 使用单链表实现:尾部添加节点(入队),头部删除节点(出队)操作
3. 这是一个带有头节点的队列,front指针始终指向头节点
'''

#定义链式队列节点
class Node:
    def __init__(self, value):
        self.data = value
        self.next = None


# 定义队列函数
class Queue:
    #队列初始化
    def __init__(self):
        self.front = Node(None)
        self.rear = self.front

    #判断队列是否为空
    def is_empty(self):
        return self.rear == self.front

    # 元素入队
    def enQueue(self, element):
        n = Node(element)
        self.rear.next = n
        self.rear = n

    # 队列元素出队
    def deQueue(self):
        if self.is_empty():
            print("队列为空")
            return
        temp = self.front.next
        self.front.next = self.front.next.next
        if self.rear == temp:
            self.rear = self.front
        del temp


    # 获取队首元素
    def gettop(self):
        if self.is_empty():
            print("队列为空")
            return
        return self.front.next.data

    # 遍历队列
    def display(self):
        if self.is_empty():
            print("队列为空")
            return
        cur = self.front.next
        while cur != None:
            print(cur.data, end=" ")
            cur = cur.next
        print()


    # 清空队列
    def clear(self):
        while self.front.next != None:
            temp = self.front.next
            self.front.next = temp.next
        self.rear = self.front


    # 返回队列长度
    def size(self):
        cur = self.front.next
        count = 0
        while cur != None:
            count += 1
            cur = cur.next
        return count


queue = Queue()
print("-----------------------------")
print("初始化的链式队列:", queue)
print("-----------------------------")
print("当前队列是否为空:", queue.is_empty())
print("-----------------------------")
print("入队前队列元素为:", end="")
queue.display()
queue.enQueue(1)
queue.enQueue(47)
queue.enQueue("tr")
print("入队后队列元素为:", end="")
queue.display()
print("-----------------------------")
print("当前队列长度为:", queue.size())
print("-----------------------------")
print("当前队列头部元素为:", queue.gettop())
print("-----------------------------")
print("出队前队列元素为:", end="")
queue.display()
queue.deQueue()
print("出队后队列元素为:", end="")
queue.display()
print("-----------------------------")
print("当前队列是否为空:", queue.is_empty())
print("-----------------------------")
print("清空后队列元素为:", end="")
queue.display()
queue.clear()
print("出队后队列元素为:", end="")
queue.display()
print("-----------------------------")
-----------------------------
初始化的链式队列: <__main__.Queue object at 0x000001BA943A9A00>
-----------------------------
当前队列是否为空: True
-----------------------------
入队前队列元素为:队列为空
入队后队列元素为:1 47 tr 
-----------------------------
当前队列长度为: 3
-----------------------------
当前队列头部元素为: 1
-----------------------------
出队前队列元素为:1 47 tr 
出队后队列元素为:47 tr 
-----------------------------
当前队列是否为空: False
-----------------------------
清空后队列元素为:47 tr 
出队后队列元素为:队列为空
-----------------------------

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

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

相关文章

springcloud之服务集群注册与发现 Eureka

前言 1&#xff1a;对于能提供完整领域服务接口功能的RPC而言&#xff0c;例如&#xff1b;gRPC、Thrift、Dubbo等&#xff0c;服务的注册与发现都是核心功能中非常重要的一环&#xff0c;使得微服务得到统一管理。 2&#xff1a;在分布式领域中有个著名的CAP理论&#xff1b;…

Vue3 + Element plus 实现切换el-radio前二次确认

Vue3 Element plus 实现切换el-radio前二次确认 场景&#xff1a;点击切换el-radio之前判断当前内容是否有改变&#xff0c;如有改变弹窗提示切换el-radio将销毁操作&#xff0c;弹窗二次确认是否切换 问题&#xff1a; el-radio 没有提供类似于beforeUpdate这样的钩子去处理这…

探索极简计算的新边界:从Uxn虚拟机看未来编程生态

越来越多的开发者追求复杂度和功能性的极致,然而,有一个小众的编程社区选择了截然不同的道路——极简主义。Uxn虚拟机便是这一思潮的代表之一。它通过简洁的指令集和有限的硬件资源模拟,试图打造一种可以在多种设备上运行的便携性编程环境。 与主流的重型操作系统和复杂…

HTB:Legacy[WriteUP]

目录 连接至HTB服务器并启动靶机 1.How many TCP ports are open on Legacy? 2.What is the 2008 CVE ID for a vulnerability in SMB that allows for remote code execution? 3.What is the name of the Metasploit module that exploits CVE-2008-4250? 4.When expl…

VS+QT 自定义插件变成动态库加载及使用

一、前言 有个界面需要重复使用某个自定义的控件&#xff0c;希望自定义控件能够像动态库文件那样&#xff0c;添加引用lib就能使用&#xff0c;经过多次太坑后&#xff0c;总结如下 二、实现方式 ① 新建项目&#xff0c;选择"Qt Designer Custom Widget" 创建自定…

Springboot从入门到起飞-【day01】

个人主页→VON 收录专栏→Springboot从入门到起飞 一、前言 经过了近两个月的沉淀开始了新专栏的学习&#xff0c;经过深思熟虑还是决定重新学习java&#xff0c;因为基础部分东西太多太乱就不进行逐一的更新了&#xff0c;等到学完了一同进行更新。 二、Springboot简要概述 …

kafka消息队列核心内容及常见问题

目录 1. 使用消息队列的目的&#xff08;优点与缺点&#xff09; 2. 常见各消息队列对比 3. kafka介绍 3.1 kafka简介 3.2 kafka特点 3.3 kafka系统架构 3.4 设置数据可靠性 3.4.1 Topic 分区副本 3.4.2 消息确认机制 4. 常见问题&#xff08;面试题&#xff09; 4.…

Springboot 接入 WebSocket 实战

Springboot 接入 WebSocket 实战 前言&#xff1a; WebSocket协议是基于TCP的一种新的网络协议。它实现了浏览器与服务器全双工(full-duplex)通信——允许服务器主动发送信息给客户端。 简单理解&#xff1a; 1&#xff0c;常见开发过程中我们知道 Http协议&#xff0c;客户端…

LED显示器闪烁故障原因及解决方法

随着电子显示屏在各行各业的广泛应用&#xff0c;LED显示器因其高亮度、节能和灵活的宣传功能&#xff0c;成为了宣传推广的重要工具。然而&#xff0c;LED显示器在使用过程中有时会出现闪烁的现象&#xff0c;这不仅影响了显示效果&#xff0c;还可能影响用户体验。针对这一问…

【layui】多文件上传组件实现

插件预览效果&#xff1a; 需要引入layui的脚本文件layui.js和样式文件layui.css html代码&#xff1a; <div class"layui-input-block"><div class"layui-upload-list"><table class"layui-table"><colgroup><col…

18936 手串

### 思路 1. **输入处理**&#xff1a;读取输入的n, m, c&#xff0c;以及每个串珠的颜色信息。 2. **颜色位置记录**&#xff1a;使用一个字典来记录每种颜色出现的位置。 3. **检查颜色分布**&#xff1a;遍历每种颜色&#xff0c;检查其在任意连续m个串珠中是否出现超过一次…

【Flask】Flask数据库

【Flask】Flask数据库 1.概述2.使用Flask-SQLAlchemy管理数据库3.定义模型4.关系5.数据库操作创建表插入行修改行删除行查询行 1.概述 大多数的数据库引擎都有对应的 Python 包&#xff0c;包括开源包和商业包。Flask 并不限制你使用何种类型的数据库包&#xff0c;因此可以根…

Java体系中的泛型

1. 泛型 一般的类和方法&#xff0c;只能够使用基本类型&#xff0c;要么是自定义的类&#xff0c;如果要编写可以应用于多种数据类型的代码&#xff0c;这种刻板的限制对代码的约束就会很大&#xff0c;那么如何实现可应用于多种数据类型的代码&#xff0c;而不局限于单一一种…

第5篇:DDOS病毒----应急响应之Linux实战篇

现象描述 某服务器网络资源异常,感染该木马病毒的服务器会占用网络带宽&#xff0c;甚至影响网络业务正常应用。 系统分析 针对日志服务器病毒事件排查情况&#xff1a; 在开机启动项/etc/rc.d/rc.local发现可疑的sh.sh脚本&#xff0c;进一步跟踪sh.sh脚本,这是一个检测病毒…

C++从入门到起飞之——AVL树 全方位剖析!

&#x1f308;个人主页&#xff1a;秋风起&#xff0c;再归来~&#x1f525;系列专栏&#xff1a;C从入门到起飞 &#x1f516;克心守己&#xff0c;律己则安 目录 1. AVL的概念 2. AVL树的实现 2.1 AVL树的结构 2.2 AVL树的插⼊ >AVL树插⼊⼀个值的⼤概过程 &…

Rocky linux 修改ip地址, rocky服务器修改静态地址, rocky虚拟机修改ip

1. 更新yum yum update 2. 安装ifconfig yum install net-tools 3. 修改配置 vi /etc/NetworkManager/system-connections/ens33.nmconnection 将ipv4内容修改如下&#xff1a; # 自动改为手动 methodmanual # 网关为vm ware 查看网关地址 address你想改为的ip/24,网关 #dns不…

Qml 分组动画(二) 动画嵌套(自学笔记)

分组动画嵌套示例&#xff0c;直接看效果&#xff0c; 做一个踢足球的示例 下面两个Rectangle 制作渐变的天空和大地 下面这个Rectangle 用于放置足球图片&#xff0c; 由于足球图片直接从网上下载的 没有找到合适大小的图片 &#xff0c;所以用 一个矩形框作限制&#xff0c;…

闲谈Promise

预备知识 回调函数&#xff1a;当一个函数作为参数传入另一个函数中&#xff0c;并且它不会立刻执行&#xff0c;当满足一定条件之后&#xff0c;才会执行&#xff0c;这种函数称为回调函数。比如&#xff1a;定时器。异步任务&#xff1a;与之对应的概念是同步任务&#xff0…

【JVM】面试篇

1 什么是JVM&#xff1f; 1.1 定义 JVM 指的是Java虚拟机&#xff08; Java Virtual Machine &#xff09;。JVM 本质上是一个运行在计算机上的程序&#xff0c;他的职责是运行Java字节码文件&#xff0c;Java虚拟机上可以运行Java、Kotlin、Scala、Groovy等语言。 启动这个程…

电子电气架构---软件定义汽车的新兴生态系统

我是穿拖鞋的汉子&#xff0c;魔都中坚持长期主义的汽车电子工程师。 老规矩&#xff0c;分享一段喜欢的文字&#xff0c;避免自己成为高知识低文化的工程师&#xff1a; 屏蔽力是信息过载时代一个人的特殊竞争力&#xff0c;任何消耗你的人和事&#xff0c;多看一眼都是你的不…