Python----数据结构(队列,顺序队列,链式队列,双端队列)
一、队列
1.1、概念
队列(Queue):也是一种基本的数据结构,在队列中的插入和删除都遵循先进先出(First in First out,FIFO)的原则。元素可以在任何时刻从队尾插入,但是只有在队列最前面 的元素才能被取出或者删除。通常将队列中允许插入的一端称为队尾,将允许删除的一 端称为队头。队列不允许在中间部位进行操作!
1.2、操作
栈使用两种基本操作:入队(push) 和 出队(pop):
- 入队:将数据放入队尾
- 出队:将队首数据移除
1.3、特点
1.先入先出(FIFO, First In FirstOut),后入后出(LILO, Last In Last Out)
2.除头尾节点之外,每个元素有一个前驱,一个后继
1.4、队列常用操作
方法名 | 描述 | 时间复杂度 |
---|---|---|
push( ) | 元素入队,即将元素添加至队尾 | $O(1)$ |
pop( ) | 队首元素出队 | $O(1)$ |
top( ) | 访问队首元素 | $O(1)$ |
python中有现成的队列类queue.Queue
二、顺序队列
2.1、初始化
def __init__(self):
"""初始化一个空队列,使用列表作为存储容器。"""
self.list = [] # 使用列表存储队列元素
2.2、入队
def put(self, data):
"""将数据放入队列末尾。
Args:
data: 要放入队列的数据。
"""
self.list.append(data) # 使用列表的 append 方法将数据添加到队列末尾
2.3、出队
def get(self):
"""从队列头部取出数据。
Returns:
从队列中取出的数据。
"""
if self.is_empty(): # 检查队列是否为空
print("队列为空,无法取出数据。") # 打印提示信息
return None # 返回 None,指示无法取出数据
return self.list.pop(0) # 从列表头部弹出数据,遵循 FIFO 原则
2.4、获取队长度
def size(self):
"""返回队列中元素的数量。
Returns:
队列中元素的数量。
"""
return len(self.list) # 使用 len 函数返回列表的长度
2.5、判断是否为空
def is_empty(self):
"""检查队列是否为空。
Returns:
如果队列为空返回 True,否则返回 False。
"""
return self.list == [] # 检查列表是否为空
2.6、完整代码
class Queue:
def __init__(self):
"""初始化一个空队列,使用列表作为存储容器。"""
self.list = [] # 使用列表存储队列元素
def is_empty(self):
"""检查队列是否为空。
Returns:
如果队列为空返回 True,否则返回 False。
"""
return self.list == [] # 检查列表是否为空
def put(self, data):
"""将数据放入队列末尾。
Args:
data: 要放入队列的数据。
"""
self.list.append(data) # 使用列表的 append 方法将数据添加到队列末尾
def get(self):
"""从队列头部取出数据。
Returns:
从队列中取出的数据。
"""
if self.is_empty(): # 检查队列是否为空
print("队列为空,无法取出数据。") # 打印提示信息
return None # 返回 None,指示无法取出数据
return self.list.pop(0) # 从列表头部弹出数据,遵循 FIFO 原则
def size(self):
"""返回队列中元素的数量。
Returns:
队列中元素的数量。
"""
return len(self.list) # 使用 len 函数返回列表的长度
if __name__ == '__main__':
q = Queue() # 创建一个队列实例
q.put(10) # 将 10 放入队列
q.put(20) # 将 20 放入队列
q.put(30) # 将 30 放入队列
q.put(40) # 将 40 放入队列
print(q.get()) # 从队列中取出并打印第一个元素(10)
print(q.size()) # 打印队列当前的大小(3)
三、链队列
3.1、初始化
class Node:
def __init__(self, data):
"""初始化节点,包含数据和指向下一个节点的指针。
Args:
data: 节点存储的数据。
"""
self.data = data # 节点数据
self.next = None # 初始时,节点的 next 指向 None
def __init__(self):
"""初始化一个空队列,使用头节点作为哨兵。"""
self.head = Node(0) # 哨兵节点,方便操作
3.2、入队
def put(self, data):
"""将数据放入队列末尾。
Args:
data: 要放入队列的数据。
"""
new_node = Node(data) # 创建新节点
current = self.head.next # 从第一个有效节点开始
if current is None:
self.head.next = new_node # 如果队列为空,直接将新节点作为队头
else:
# 遍历到队列的末尾
while current.next is not None:
current = current.next
current.next = new_node # 将新节点添加到队列末尾
3.3、出队
def get(self):
"""从队列头部取出数据。如果队列为空,打印提示信息。
Returns:
从队列中取出的数据。
"""
if self.is_empty(): # 检查队列是否为空
print("队列为空,无法取出数据。") # 打印提示信息
return None # 返回 None,指示无法取出数据
current = self.head.next # 获取队列头部元素
self.head.next = current.next # 移动头指针到下一个节点
return current.data # 返回取出的数据
3.4、获取队长度
def size(self):
"""返回队列中元素的数量。
Returns:
队列中元素的数量。
"""
count = 0
current = self.head.next # 从第一个有效节点开始
while current is not None:
count += 1
current = current.next # 移动到下一个节点
return count # 返回计数
3.5、判断是否为空
def is_empty(self):
"""检查队列是否为空。
Returns:
如果队列为空返回 True,否则返回 False。
"""
return self.head.next is None # 如果头节点的 next 为 None,队列为空
3.6、完整代码
class Node:
def __init__(self, data):
"""初始化节点,包含数据和指向下一个节点的指针。
Args:
data: 节点存储的数据。
"""
self.data = data # 节点数据
self.next = None # 初始时,节点的 next 指向 None
class QueueLink:
def __init__(self):
"""初始化一个空队列,使用头节点作为哨兵。"""
self.head = Node(0) # 哨兵节点,方便操作
def is_empty(self):
"""检查队列是否为空。
Returns:
如果队列为空返回 True,否则返回 False。
"""
return self.head.next is None # 如果头节点的 next 为 None,队列为空
def put(self, data):
"""将数据放入队列末尾。
Args:
data: 要放入队列的数据。
"""
new_node = Node(data) # 创建新节点
current = self.head.next # 从第一个有效节点开始
if current is None:
self.head.next = new_node # 如果队列为空,直接将新节点作为队头
else:
# 遍历到队列的末尾
while current.next is not None:
current = current.next
current.next = new_node # 将新节点添加到队列末尾
def get(self):
"""从队列头部取出数据。如果队列为空,打印提示信息。
Returns:
从队列中取出的数据。
"""
if self.is_empty(): # 检查队列是否为空
print("队列为空,无法取出数据。") # 打印提示信息
return None # 返回 None,指示无法取出数据
current = self.head.next # 获取队列头部元素
self.head.next = current.next # 移动头指针到下一个节点
return current.data # 返回取出的数据
def size(self):
"""返回队列中元素的数量。
Returns:
队列中元素的数量。
"""
count = 0
current = self.head.next # 从第一个有效节点开始
while current is not None:
count += 1
current = current.next # 移动到下一个节点
return count # 返回计数
if __name__ == '__main__':
q = QueueLink() # 创建一个队列实例
q.put(10) # 将 10 放入队列
q.put(20) # 将 20 放入队列
q.put(30) # 将 30 放入队列
q.put(40) # 将 40 放入队列
print(q.get()) # 从队列中取出并打印第一个元素(10)
print(q.size()) # 打印队列当前的大小(3)
四、双端队列
4.1、初始化
def __init__(self):
"""初始化一个空双端队列,使用列表作为存储容器。"""
self.list = [] # 使用列表来存储双端队列的元素
4.2、队列前端添加元素
def add_front(self, data):
"""在队列前端添加元素。
Args:
data: 要添加到队列前端的数据。
"""
self.list.insert(0, data) # 使用 insert 方法在列表的开头插入新元素
4.3、队列后端添加元素
def add_rear(self, data):
"""在队列后端添加元素。
Args:
data: 要添加到队列后端的数据。
"""
self.list.append(data) # 使用 append 方法在列表的末尾添加新元素
4.4、队列前端移除元素
def remove_front(self):
"""从队列前端移除并返回元素。
Returns:
被移除的元素,如果队列为空,则会引发异常。
"""
if self.is_empty(): # 检查队列是否为空
print("队列为空,无法从前端移除数据。")
return None # 如果为空,返回 None
return self.list.pop(0) # 从列表的开头移除并返回元素
4.5、队列后端移除元素
def remove_rear(self):
"""从队列后端移除并返回元素。
Returns:
被移除的元素,如果队列为空,则会引发异常。
"""
if self.is_empty(): # 检查队列是否为空
print("队列为空,无法从后端移除数据。")
return None # 如果为空,返回 None
return self.list.pop() # 从列表的末尾移除并返回元素
4.6、判断是否为空
def is_empty(self):
"""检查队列是否为空。
Returns:
如果队列为空返回 True,否则返回 False。
"""
return self.list == [] # 检查列表是否为空
4.7、获取队长度
def size(self):
"""返回队列中元素的数量。
Returns:
队列中元素的数量。
"""
return len(self.list) # 返回列表的长度
4.8、完整代码
class Deque:
def __init__(self):
"""初始化一个空双端队列,使用列表作为存储容器。"""
self.list = [] # 使用列表来存储双端队列的元素
def add_front(self, data):
"""在队列前端添加元素。
Args:
data: 要添加到队列前端的数据。
"""
self.list.insert(0, data) # 使用 insert 方法在列表的开头插入新元素
def add_rear(self, data):
"""在队列后端添加元素。
Args:
data: 要添加到队列后端的数据。
"""
self.list.append(data) # 使用 append 方法在列表的末尾添加新元素
def remove_front(self):
"""从队列前端移除并返回元素。
Returns:
被移除的元素,如果队列为空,则会引发异常。
"""
if self.is_empty(): # 检查队列是否为空
print("队列为空,无法从前端移除数据。")
return None # 如果为空,返回 None
return self.list.pop(0) # 从列表的开头移除并返回元素
def remove_rear(self):
"""从队列后端移除并返回元素。
Returns:
被移除的元素,如果队列为空,则会引发异常。
"""
if self.is_empty(): # 检查队列是否为空
print("队列为空,无法从后端移除数据。")
return None # 如果为空,返回 None
return self.list.pop() # 从列表的末尾移除并返回元素
def is_empty(self):
"""检查队列是否为空。
Returns:
如果队列为空返回 True,否则返回 False。
"""
return self.list == [] # 检查列表是否为空
def size(self):
"""返回队列中元素的数量。
Returns:
队列中元素的数量。
"""
return len(self.list) # 返回列表的长度
if __name__ == '__main__':
dq = Deque() # 创建一个双端队列实例
dq.add_front(10) # 在队列前端添加 10
dq.add_front(20) # 在队列前端添加 20
dq.add_front(30) # 在队列前端添加 30
dq.add_rear(90) # 在队列后端添加 90
dq.add_rear(80) # 在队列后端添加 80
dq.add_rear(70) # 在队列后端添加 70
print(dq.remove_front()) # 从队列前端移除并打印(30)
print(dq.remove_rear()) # 从队列后端移除并打印(70)
print(dq.size()) # 打印当前队列的大小