数据结构------队列

本文介绍了数据结构中的队列,包括其FIFO特性、环状队列的实现以及Python中的deque双端队列。通过实例展示了如何使用队列解决迷宫问题,采用广度优先搜索策略。此外,还探讨了双向队列在实现tail命令中的作用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

队列

队列(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)]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值