目录
- 0. 前言
- 1. 了解堆栈
- 2.代码实现
- 3. 演示效果
- 其他PyQt5文章
0. 前言
本文使用 PyQt5制作图形化界面演示数据结构中的堆栈操作
操作系统:Windows10 专业版
开发环境:Pycahrm Comunity 2022.3
Python解释器版本:Python3.8
第三方库:PyQt5
1. 了解堆栈
在计算机科学中,堆栈(Stack),也常被称为栈,是一种抽象的数据结构,它是一种只能从一个端添加元素和删除元素的线性数据结构。这一端被称为“栈顶”,相对地,把另一端称为“栈底”。根据这个定义,可以推断出后进先出(LIFO,Last In First Out)这个特性。
堆栈有以下几个基本操作:
- push: 将一个元素添加到栈顶
- pop: 从栈顶移除一个元素,并返回这个元素的值
- peek/top: 返回栈顶的元素值,但不将其移除
- is_empty: 返回栈是否为空
堆栈通常使用数组或链表实现。如果使用数组实现,需要考虑动态扩容的情况。如果使用链表实现,需要注意在链表头进行操作,否则操作的时间复杂度将变为O(n)。
堆栈通常用作典型的临时存储(例如在递归函数中存储函数的返回地址),或者是需要逆序输出元素的应用程序那么在这样的应用中,堆栈的弹出顺序就可以实现逆序的要求。
例如:
假设你要洗堆满了碗,你会把碗一层一层地往上堆放。当你洗完一个碗放入放碗柜时,你把刚才放在最上层的碗取下来,这就是一个栈的操作过程。
当你需要使用碗时,你从栈顶拿下一个碗。如果你拿下的碗与你想要使用的碗不一样,你就把拿下的碗再放回去,这样使用的就是最后一个放上去的碗。这个过程叫做“后进先出”,或者LIFO(Last 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. 演示效果
提供了四个操作:
- 入栈
- 出栈
- 栈顶元素查询
- 堆栈初始化(清空)
运行代码可以看到堆栈中是有三个元素(绿色框框)在其中,这是我们在代码中提前预设的三个值
现在输入13,然后将它Push到栈中,可以看到 多了一个元素:
然后取其Peek(顶端)的值,看看是否如愿:
如我们压入栈中的一样,就是13,但是并不会将它从栈中取出
现在我们将其Pop,看看会是怎样的情形:
执行完Pop操作后,将栈顶元素13取出,并且栈中也少了一个元素
其他PyQt5文章
基于PyQt5的图形化界面开发——自制MQTT客户端
基于PyQt5的图形化界面开发——Windows内存资源监视助手[附带编译exe教程]
基于PyQt5的图形化界面开发——模拟医院管理系统
基于PyQt5的图形化界面开发——自制ssh工具
基于PyQt5的图形化界面开发——PyQt示例_计算器
基于PyQt5的图形化界面开发——PyQt示例_扫雷
基于PyQt5的图形化界面开发——自制Redis图形化客户端(文末附源码)
基于PyQt5的图形化界面开发——堆栈动画演示
基于PyQt5的图形化界面开发——队列动画演示