队列
队列(Queue)是有序集合,仅允许在队尾插入,在队头进行删除.
性质
队列FIFO先进先出的原则进行操作
队列的实现
队列的实现能不能用简单的列表来实现呢?
如下:
…
队列的实现方式----环状队列:
空队的时候如下:rear和front共同指向0的位置
当有元素入队时:
当元素a1,a2出队,同时a9,a10入队后,front和rear的位置如图所示:此时队满
(1)队首指针前进1:front = (front+1)%MaxSize
(2)队尾指针前进1: = (rear+1)%MaxSize
(3)队空条件:rear = front
(4)队满条件:(rear+1)%Maxsize == front
代码实现:
class Queue():
def __init__(self, size = 100):
self.queue = [0 for _ in range(size)]
self.size = size
self.front = 0
self.rear = 0
def push(self,val):
self.rear = (self.rear+1) % self.size
self.queue[self.rear] = val
def pop(self):
if not self.is_empty():
self.front = (self.front + 1) % self.size
return self.queue[self.front]
else:
raise IndexError
# 判断队满
def is_filled(self):
if (self.rear + 1) % self.size == self.front:
return True
双向队列
双向队列的两端都支持进队和出队操作
python中提供的deque就实现了双向队列.
基本操作
from collections import deque
q = deque([1,2,3,4,5], 5) # 定义队列的长度为5,队列为指定的列表
q.append(6) # 队尾进队,会将1出队,而6进队
print(q) # deque([2, 3, 4, 5, 6], maxlen=5)
print(q.popleft()) # 队首出队,此时2出队
q.appendleft(90) #队首进队
print(q) # deque([90, 3, 4, 5, 6], maxlen=5)
print(q.pop()) #队尾出队6
用双向队列实现tail命令
def tail(n):
with open('test.txt','r') as f:
q = deque(f, n)
return q
for line in tail(5):
print(line, end = '')
迷宫问题–广度优先搜索
如图为迷宫的起点和终点位置,需要找到一条合适的路径到达终点.
广度优先思路:从开始节点,寻找所有接下来能继续走的点,从这些点继续寻找,直到到达终点.
(1)这样我们用队列来存储当前正在进行的点.
(2)走过的点进行标记,其他路径不会再走这些点.
(3)当我们走到终点时,需要知道这条完整的路径,但是队列中只保存了当前的位置点,这样的话我们就需要额外的空间来存储当前的位置点的来源位置点,这样我们就可以进行回溯.
如图:
代码实现:
from collections import deque
maze = [
[1,1,1,1,1,1,1,1,1,1],
[1,0,0,1,0,0,0,1,0,1],
[1,0,0,1,0,0,0,1,0,1],
[1,0,0,0,0,1,1,0,0,1],
[1,0,1,1,1,0,0,0,0,1],
[1,0,0,0,1,0,0,0,0,1],
[1,0,1,0,0,0,1,0,0,1],
[1,0,1,1,1,0,1,1,0,1],
[1,1,0,0,0,0,0,1,0,1],
[1,1,1,1,1,1,1,1,1,1],
]
# 当前点想x,y的四个方向点:
dirs = [
lambda x,y:(x+1,y),
lambda x,y:(x-1,y),
lambda x,y:(x,y+1),
lambda x,y:(x,y-1)
]
def maze_q(x1,y1,x2,y2):
# x1,y1为起点,x2,y2为终点
queue = deque()
queue.append((x1,y1,-1))
path = []
while len(queue):
curNode = queue.pop()
path.append(curNode)
if curNode[0] == x2 and curNode[1]==y2:
#终点
print_path(path)
return
for dir in dirs:
nextNode = dir(curNode[0],curNode[1])
if maze[nextNode[0]][nextNode[1]] == 0:
queue.appendleft((nextNode[0],nextNode[1], len(path)-1))
maze[nextNode[0]][nextNode[1]] = 2 # 标记已经走过
else:
print('没有路径')
def print_path(path):
curNode = path[-1]
real_path = []
while curNode[2] != -1:
real_path.append(curNode[:2])
curNode = path[curNode[2]]
maze_q(1,1,8,8)
>> [(1, 1), (2, 1), (3, 1), (4, 1), (5, 1), (5, 2), (5, 3), (6, 3), (6, 4), (6, 5), (5, 5), (5, 6), (5, 7), (6, 7), (6, 8), (7, 8), (8, 8)]