概述
队列(Queue)和栈(Stack)其实都是一个基于事务列表的数据结构。
GDScript虽然没有直接提供,但通过数组,可以轻松的实现队列和栈的效果。为了更好的语义化和限制数组多余操作,我们可以采用自定义类来封装队列和栈。通过内部的数组来存储实际的事务列表。
栈的实现
# =========================================
# 基于Godot数组实现的栈数据结构,实现压入和弹出
# =========================================
class_name Stack
var _data:Array
func _init():
_data = []
# 末尾压入值
func push(value):
_data.push_back(value)
# 弹出并返回末尾值
func pop():
return _data.pop_back()
# 显示输出数据
func show_print():
print(_data)
# 返回元素个数
func count() -> int:
return _data.size()
# 清空
func clear():
_data.clear()
测试脚本:
# 这是一个简单的ES脚本
@tool
extends EditorScript
# 运行函数
func _run():
var stack = Stack.new() # 创建栈
stack.push(1) # 压入1
stack.push(2) # 压入2
stack.show_print() # 显示数组数据
print(stack.pop()) # 弹出并显示数据
stack.show_print() # 显示数组数据
输出:
[1, 2]
2
[1]
实现括号匹配
# 检测括号匹配
func kuo_match(sttr:String)->bool:
var stac = Stack.new()
for i in range(sttr.length()):
match sttr[i]:
"[","{","(":
stac.push(sttr[i])
"]":
var end = stac.pop() # 末尾元素
if end != "[":
stac.push(end) # 重新压入末尾元素
"}":
var end = stac.pop() # 末尾元素
if end != "{":
stac.push(end) # 重新压入末尾元素
")":
var end = stac.pop() # 末尾元素
if end != "(":
stac.push(end) # 重新压入末尾元素
stac.show_print()
return stac.count()==0
@tool
extends EditorScript
func _run() -> void:
var sttr = "[789{123(345)}]"
print(kuo_match(sttr))
["["]
["["]
["["]
["["]
["[", "{"]
["[", "{"]
["[", "{"]
["[", "{"]
["[", "{", "("]
["[", "{", "("]
["[", "{", "("]
["[", "{", "("]
["[", "{"]
["["]
[]
true
16行之前的是每次循环时栈内的状态。
队列的实现
# =========================================
# 基于Godot数组实现的[队列]数据结构,实现压入和弹出
# =========================================
class_name Queue
var _data:Array
func _init():
_data = []
# 末尾压入值
func push(value):
_data.push_back(value)
# 弹出并返回第一元素值
func pop():
return _data.pop_front()
# 显示输出数据
func show_print():
print(_data)
# 返回元素个数
func count() -> int:
return _data.size()
# 清空
func clear():
_data.clear()
可以看到除了类名和16行之外,两个类的代码几乎一样。因此可以让Queue继承自Stack,然后在Queue中重写pop()
方法即可。
# =========================================
# 基于Godot数组实现的[队列]数据结构,实现压入和弹出
# =========================================
class_name Queue extends Stack
var _data:Array
func _init():
_data = []
# 弹出并返回第一元素值
func pop():
return _data.pop_front()
测试脚本:
# 这是一个简单的ES脚本
@tool
extends EditorScript
# 运行函数
func _run():
var queue = Queue.new() # 创建队列
queue.push(1) # 压入1
queue.push(2) # 压入2
queue.show_print() # 显示数组数据
print(queue.pop()) # 弹出并显示数据
queue.show_print() # 显示数组数据
输出:
[1, 2]
1
[2]
类图总结
限制长度
在其他语言的队列和栈设计中,往往要限制队列或栈的的长度。超过长度,将限制新的元素入栈或入队。
因为继承关系的设计,所以我们只需要在Stack
中增加一个max_size
属性,然后在push()
判断是否超过指定长度就可以限制新元素插入了。
修改后的Stack
代码如下:
# =========================================
# 基于Godot数组实现的栈数据结构,实现压入和弹出
# =========================================
class_name Stack
var _data:Array
var max_size:int =0 # 最大长度
func _init():
_data = []
# 末尾压入值
func push(value):
if max_size>0 and _data.size() < max_size:
_data.push_back(value)
# 弹出并返回末尾值
func pop():
return _data.pop_back()
# 显示输出数据
func show_print():
print(_data)
# 返回元素个数
func count() -> int:
return _data.size()
# 清空
func clear():
_data.clear()