栈和队列

1. 栈:后进先出

  

 

 

2. 栈的实现  

class Stack:
    def __init__(self):
        self.stack = []

    def push(self, ele):        # 进栈
        self.stack.append(ele)

    def pop(self):                # 出栈
        self.stack.pop()

    def get_top(self):            # 取栈顶
        if len(self.stack) > 0:
            return self.stack[-1]

    def is_empty(self):        # 判断栈为空
        return len(self.stack) == 0    

 

 

3. 栈的应用:括号匹配问题

def brace_match(str):
    stack = Stack()    # 调用栈对象
    match = {'}':'{',']':'[',')':'('}   # 字典中的键值对为正确括号匹配
    for i in str:
        if i in {'(','[','{'}:  # 如果是左括号,则入栈
            stack.push(i)
        else:   # 右括号的三种情况
            if stack.is_empty():    # 栈为空直接判断False
                return False
            elif stack.get_top() == match[i]:   # 栈不为空时栈顶匹配字典,匹配上为一对则出栈
                stack.pop()
            else:   # 匹配不上判断False
                return False
    if stack.is_empty():    # 直到匹配所有字符后栈为空,则说明括号匹配成功
        return True
    else:
        return False

 

 

4. 队列:先进先出

 

 

 

    

 

 

 

 

5. 环形队列:首尾相连的队列

   

 

6. 队列的实现

# 环形队列
class Queue:
    def __init__(self, size):
        self.queue = [None for _ in range(size)]
        self.size = size
        self.rear = 0   # 队尾指针
        self.front = 0  # 队首指针
    # 队尾队列
    def push(self, ele):
        if not self.is_filled():
            self.rear = (self.rear + 1) % self.size
            self.queue[self.rear] = ele
        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")
    # 队空判断
    def is_empty(self):
        return self.rear == self.front
    # 堆满判断
    def is_filled(self):
        return (self.rear + 1) % self.size == self.front

 

 

7. 经典算法题,迷宫问题

  

 

  1. 使用栈算法求迷宫问题: 深度优先搜索

# 栈思想
moze = [
    [1,1,1,1,1,1,1,1,1,1,1,1,1],
    [1,0,0,1,1,1,0,0,0,0,1,0,1],
    [1,0,0,0,0,0,1,1,1,1,1,0,1],
    [1,0,1,1,1,1,0,0,0,0,0,0,1],
    [1,0,0,0,0,0,0,1,1,0,1,1,1],
    [1,1,1,1,0,1,1,1,1,0,1,1,1],
    [1,1,0,0,0,0,0,0,0,0,1,1,1],
    [1,1,1,1,1,1,1,1,1,0,0,1,1],
    [1,1,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 moze_path(x1,y1,x2,y2):     # x1,y1为起始位置,x2,y2为终点位置
    stack = []             # 建栈,栈看做一个列表
    stack.append((x1,y1))     # 初始位置进栈
    while(len(stack)>0):      # 栈中有值继续走,没有值说明出栈到原点了,没有路走
        curNode = stack[-1]     # 取栈顶为当前的节点
        # 当栈顶等于终点位置,则说明走到终点了
        if curNode[0] == x2 and curNode[1] == y2:
            for i in stack:
                print(i)
            return True
        for dir in dirs:
            # 调用lambda函数,分别传入当前节点坐标值
            nextNode = dir(curNode[0],curNode[1])
            # 如果下一个节点能走,则进栈
            if moze[nextNode[0]][nextNode[1]] == 0:
                stack.append(nextNode)
                # 将走过的位置进行标志,防止走回头路
                moze[nextNode[0]][nextNode[1]] = 2
                break
        else:
                maze[nextNode[0]][nextNode[1]] = 2  # 这里防止重走老路
                stack.pop()
    else:
        return False

 

  2. 使用队列算法求迷宫问题:广度优先搜索

# 队列思想
from collections import deque
def moze_path_queue(x1,y1,x2,y2):
    queue = deque()    # 创建队列
    queue.append((x1,y1,-1))    # 队列为三维列表,最后元素为从某个元素进入队列的下标
    path = []                   # 存放出队的元素
    # 当队列中存在元素时,说明存在路径
    while len(queue)>0:
        curNode = queue.popleft()   # 队尾出队
        path.append(curNode)        # 将出队的元素存起
        # 到达终点后开始往前寻址
        if curNode[0] == x2 and curNode[1] == y2:
            new_curNode = path[-1]  # 初始值为出队列列表最后元素的位置
            realPath = []
            while new_curNode[2] != -1:     # -1是最开始的位置,不等于-1的时候说明没到头
                realPath.append(new_curNode[0:2])   # 存放位置坐标
                new_curNode = path[new_curNode[2]]  # new_curNode[2]为上一个过来点的下标

            realPath.append(new_curNode[0:2])
            realPath.reverse()
            for i in realPath:
                print(i)
            return True

        # 调用lambda函数,分别传入当前节点坐标值
        for dir in dirs:
            nextNode = dir(curNode[0],curNode[1])
            if moze[nextNode[0]][nextNode[1]] == 0:
                queue.append((nextNode[0],nextNode[1],len(path)-1))
                moze[nextNode[0]][nextNode[1]] = 2
                # 区别栈的就是没有break,会向所有符合的都进去,即广度优先搜索
    else:
        return False

 

posted @ 2023-01-04 23:28  无敌小豆包  阅读(15)  评论(0编辑  收藏  举报