zoukankan      html  css  js  c++  java
  • 数据结构-队列

    队列概念

      队列 Queue是一个数据集合,仅允许在列表一端插入,另一端进行删除

      进行插入的一端称为队尾(rear),插入动作称为进队或入队

      进行删除的一端称为队头(front),删除动作称为出队

      队列的性质:先进先出(First in,First out)

      队列能不能用列表实现呢?

      比较删除一个元素,列表操作的时间复杂度是O(n),这并不是我们所希望的

      那如果维护两个指针,一个指向队头,一个指向队尾,当出队删除元素时,我们只要移动队头指针就可以了,那是不是就解决了上面的问题了,似乎是解决了,但是又引出另外一个问题,就删除元素的空间是还在的,这样会很浪费空间的,那怎么充分利用这空间呢,或者说,怎么在进队时,使得进队的元素指向这些空间进行充分利用呢?

      为了解决上面问题,就引出了环形队列

    环形队列

      环形队列满足下面条件:

    • 队头(front)和队尾(rear)相等时,队列为空
    • rear + 1 = front,队满,为了区分队空,留了一小块空间
    • 实现环形队列使用取余模型
    1. 队首指针前进1:front = (front + 1) % MaxSize
    2. 队尾指针前进1:rear = (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.rear = 0 #队尾指针
            self.front = 0 #队首指针
    
        def push(self, element):
            if not self.is_filled:
                self.rear = (self.rear + 1) % self.size
                self.queue[self.rear] = element
            else:
                raise IndexError("Queue is filled.")
    
        def pop(self):
            if not self.is_empty:
                self.front = (self.front + 1) % self.size
                return self.queue[self.front]
            else:
                raise IndexError("Queue is empty.")
    
        @property
        def is_empty(self):
            return self.rear == self.front
    
        @property
        def is_filled(self):
            return (self.rear + 1) % self.size == self.front
    

    Python队列内置模块

    • 双向队列: from collections import deque(一般构造数据结构用这个,保证线程安全,用import queue)
    • 创建队列:queue = deque()
    • 进队:append()
    • 出队:popleft()
    • 双向队列队首进队:appendleft()
    • 双向队列队尾出队:pop()

      其中deque,第一参数是指定初始队列值,而第二参数则是指定队列的长度,不过它在队满的情况下,会自动出队之前的值,利用这个特性我们可以实现linux命令tail取后几行操作

    from collections import deque
    def tail(n):
        with open('test.txt', 'r') as f:
            q = deque(f, n)
            return q
    
    for line in tail(5):
        print(line, end="")
    

      利用队列实现广度优先走迷宫

    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, 0, 0, 1],
        [1, 1, 1, 1, 1, 1, 1, 1, 1, 1]
    ]
    
    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 print_r(path):
        curNode = path[-1]
    
        realpath = []
    
        while curNode[2] == -1:
            realpath.append(curNode[0:2])
            curNode = path[curNode[2]]
    
        realpath.append(curNode[0:2])  # 起点
        realpath.reverse()
        for node in realpath:
            print(node)
    
    
    def maze_path_queue(x1, y1, x2, y2):
        queue = deque()
        queue.append((x1, y1, -1))
        path = []
        while len(queue) > 0:
            curNode = queue.pop()
            path.append(curNode)
            if curNode[0] == x2 and curNode[1] == y2:
                # 终点
                print_r(path)
                return True
            for dir in dirs:
                nextNode = dir(curNode[0], curNode[1])
                if maze[nextNode[0]][nextNode[1]] == 0:
                    queue.append((nextNode[0], nextNode[1], len(path) - 1))  # 后续节点进队,记录哪个节点带他来的
                    maze[nextNode[0]][nextNode[1]] = 2  # 标记为已经走过
        else:
            print("没有路")
            return False
    
    
    maze_path_queue(1, 1, 8, 8)
    
  • 相关阅读:
    iOS的文字自适应
    指向指针的指针
    NSString的创建
    Foundation-常用结构体
    Foundation summary
    成员变量补充
    Block^
    Protocol
    Category-分类
    李明杰要在广州开课啦
  • 原文地址:https://www.cnblogs.com/xinsiwei18/p/10322883.html
Copyright © 2011-2022 走看看