目录
- 0. 前言
- 1. 了解队列
- 2. 代码实现
- 3. 效果演示
- 其他PyQt5文章
0. 前言
本文使用PyQt5制作图形化界面演示数据结构中的队列操作,与上一节队列动画相对应
基于PyQt5的图形化界面开发——队列动画演示
操作系统:Windows10 专业版
开发环境:Pycahrm Comunity 2022.3
Python解释器版本:Python3.8
第三方库:PyQt5
1. 了解队列
队列(Queue)是一种常用的数据结构,类似于现实生活中的排队,是一种先进先出(First In,First Out)的数据结构,即最先进入队列的元素最先出队。
队列具有以下几个基本操作:
- enqueue: 入队,将一个元素添加到队尾
- dequeue: 出队,从队头移除一个元素,并返回这个元素的值
- front: 队头,获取队头的元素值,但不将其移除
- is_empty: 判断队列是否为空
队列可以使用数组或链表来实现。使用数组实现队列需要考虑到如何动态扩容,而链表实现则需要注意在队尾进行操作,否则操作的时间复杂度将变为 O(n)。
队列在很多场景中都得到了广泛应用,比如现实中的排队、计算机中的进程调度、网络中的数据传输等等。例如,当你使用计算机浏览网页时,网络数据被保存在队列中,一个请求还没有处理完毕时,其他的请求需要等待它前面的请求先完成,这就是队列的应用之一。
例如:
生活中排队买票是队列的一个常见例子。
假设你要去银行柜台排队取钱,如果前面没有人,你就可以直接到柜台取钱,而如果前面有人,你就必须排队等待。
如果你排在排队的最后,那么你需要等待所有其他人先取完钱后才能取钱,即先进入排队的人先取完钱后才轮到你。这就是队列的先进先出原则,即最先进入队列的元素最先出队。
这种情形也常用在电影院和公共汽车站中。在电影院中,你需要排队买票,然后按照先进先出的原则依次进入电影院;在公共汽车站中,你需要排队等车,车到后按照先进先出的原则上车。
在计算机中,进程调度和消息队列也应用了队列的先进先出原则。例如,当计算机向一个进程发送多个消息时,该进程会按照先进先出的原则依次处理每一个消息,这就是队列的应用之一。
堆栈特性为后进先出,也叫LIFO(Last In First Out);那么队列的特性与之对应为先进先出,又叫FIFO(First In First Out)。
2. 代码实现
from PyQt5.QtWidgets import *
from PyQt5.QtGui import *
from PyQt5.QtCore import *
import sys
class Node:
def __init__(self, data):
self.data = data
self.next = None
class Queue:
def __init__(self):
self.head = None
self.tail = None
def enqueue(self, data):
new_node = Node(data)
if self.tail is None:
self.head = new_node
self.tail = new_node
else:
self.tail.next = new_node
self.tail = new_node
def dequeue(self):
if self.head is not None:
data = self.head.data
self.head = self.head.next
if self.head is None:
self.tail = None
return data
else:
return None
def front(self):
if self.head is not None:
return self.head.data
else:
return None
def is_empty(self):
return self.head is None
def display(self, scene):
pen = QPen(QColor(0, 255, 0))
font = QFont("Arial", 10)
y = 100
current_node = self.head
while current_node is not None:
# Draw node rectangle
scene.addRect(50, y, 50, 50, pen)
# Draw node text
text = scene.addText(str(current_node.data), font)
text.setDefaultTextColor(QColor(255, 255, 255))
text.setPos(70, y + 10)
current_node = current_node.next
y += 70
class MainWindow(QMainWindow):
def __init__(self):
super().__init__()
self.setWindowTitle("Queue Demo")
self.setFixedSize(500, 500)
self.scene = QGraphicsScene(self)
self.view = QGraphicsView(self.scene, self)
self.view.setGeometry(0, 0, 500, 500)
self.queue = Queue()
self.queue.enqueue(10)
self.queue.enqueue(20)
self.queue.enqueue(30)
self.queue.display(self.scene)
# Add UI elements
enqueue_button = QPushButton("Enqueue", self)
enqueue_button.move(10, 10)
enqueue_button.clicked.connect(self.handle_enqueue)
dequeue_button = QPushButton("Dequeue", self)
dequeue_button.move(10, 40)
dequeue_button.clicked.connect(self.handle_dequeue)
front_button = QPushButton("Front", self)
front_button.move(10, 70)
front_button.clicked.connect(self.handle_front)
clear_button = QPushButton("Clear", self)
clear_button.move(10, 100)
clear_button.clicked.connect(self.handle_clear)
self.data_edit = QLineEdit(self)
self.data_edit.move(100, 10)
def handle_enqueue(self):
data = self.data_edit.text()
if data != "":
self.queue.enqueue(data)
self.scene.clear()
self.queue.display(self.scene)
def handle_dequeue(self):
data = self.queue.dequeue()
if data is not None:
QMessageBox.information(self, "Dequeue", "Dequeued value: " + str(data))
self.scene.clear()
self.queue.display(self.scene)
else:
QMessageBox.warning(self, "Dequeue", "Queue is empty")
def handle_front(self):
data = self.queue.front()
if data is not None:
QMessageBox.information(self, "Front", "Front value: " + str(data))
else:
QMessageBox.warning(self, "Front", "Queue is empty")
def handle_clear(self):
self.queue = Queue()
self.scene.clear()
if __name__ == "__main__":
app = QApplication(sys.argv)
window = MainWindow()
window.show()
sys.exit(app.exec_())
3. 效果演示
还是初始化后存有三个元素,你可以使用最后一个按钮Clear给它清空
清空了所有元素:
然后入队两个元素,分别是1和2:
现在我们进行队首元素查询,这个操作不应该让元素出队,并且应该遵循先进先出的原则,应该查询到1,演示效果的确如此:
现在出队两次,那么就又回到了初始的转态,即空队,现在再进行出队会怎么样呢?
收到了提示队列为空:
其他PyQt5文章
基于PyQt5的图形化界面开发——自制MQTT客户端
基于PyQt5的图形化界面开发——Windows内存资源监视助手[附带编译exe教程]
基于PyQt5的图形化界面开发——模拟医院管理系统
基于PyQt5的图形化界面开发——自制ssh工具
基于PyQt5的图形化界面开发——PyQt示例_计算器
基于PyQt5的图形化界面开发——PyQt示例_扫雷
基于PyQt5的图形化界面开发——自制Redis图形化客户端(文末附源码)
基于PyQt5的图形化界面开发——堆栈动画演示
基于PyQt5的图形化界面开发——队列动画演示