005数据结构之栈和队列

1.栈

栈是一个数据集合,只能在一端进行插入或删除的操作
特点:后进先出
概念:栈顶/栈底
操作:进栈(push)/出栈(pop)/取栈顶(get_top)

补充

数据结构按逻辑结构分类:
1.线性结构 :数据结构中的元素存在一对一的相互关系
2.树结构:数据结构中的元素存在一对多的相互关系
3.图结构:数据结合中的元素存在多对一的相互关系

列表中的元素在计算机中的存储方式:顺序存储(连续的内存),实际上存储的是元素的地址

数组与列表有两个不同点:
1.数组元素的类型必须相同
2.数组长度固定

1.1代码

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

    def push(self,element):
        self.stack.append(element)

    def pop(self):
        return self.stack.pop()

    def get_top(self):
        return self.stack[-1]
    def is_empty(self):
        return len(self.stack)==0


'''
括号匹配问题
'''

def brace_math(s):
    match={'}':'{',']':'[',')':'('}
    stack=Stack()
    for ch in s:
        if ch in {'(','[','{'}:     #左括号进栈
            stack.push(ch)
        else:                      #如果当前是右括号
            if stack.is_empty():
                return False

            elif stack.get_top()==match[ch]:
                stack.pop()
            else:    #stack.get_top() !=match[ch]  当前右括号与栈顶的左括号不匹配
                return False
    if stack.is_empty():
        return True
    else:
        return False

st=list('(()[][{()[]}])')
print(brace_math(st))

1.2用栈解决迷宫问题

栈–深度优先搜索(回溯法)

思路:

从一个节点开始,任意找下一个能走的点,当找不到能走的点时,退回上一个点寻找是否有其他方向的点。
#使用栈存储当前的路径
#所得路径不一定是最短的

代码

maze=[
    [1,1,1,1,1],
    [1,0,1,1,1],
    [1,0,0,1,1],
    [1,1,0,0,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)
]
#这是一个列表,元素是函数表达式,dirs[0](x,y)=(x+1,y)

def maze_path(x1,y1,x2,y2):
    stack=[]
    stack.append((x1,y1))
    while(len(stack)>0):
        cur_Node=stack[-1]
        if cur_Node[0]==x2 and cur_Node[1]==y2:
            #走到终点了
            for p in stack:
                print(p)
            return True
        #x,y四个方向:x-1,y-1,x+1,y+1
        for dir in dirs:
            next_Node=dir(cur_Node[0],cur_Node[1])  #将当前节点依次放进dirs中的四个函数表达式,如果得到的下一个节点可以走(值为0),则进栈,并将其值赋2,结束此次的for循环
            #如果下一个节点能走
            if maze[next_Node[0]][next_Node[1]]==0:
                stack.append(next_Node)
                maze[next_Node[0]][next_Node[1]]=2 #2表示已经走过
                break
        else:     #与for对应,表示for循环结束了还是没有任何操作,执行以下语句,开始回退,
            # print('next_Node',next_Node)
            maze[cur_Node[0]][cur_Node[1]]=2
            stack.pop()

    else:
        print('没有路')
        return False

maze_path(1,1,3,3)

2.队列

队列(Queue):是一个数据集合
特点:仅允许在列表的一端进行插入,另一端进行删除
概念:插入动作称为进队或入队,进行插入的一端称为队尾(rear);删除动作称为出队,进行删除的一端称为队头(front)
性质:先进先出

2.1代码

#队列的实现方式--环形队列
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')

    #判断队空
    def is_empty(self):
        return self.rear==self.front

    #判断队满
    def is_filled(self):
        return (self.rear+1)%self.size==self.front


q=Queue(6)
for i in range(5):
    q.push(i)
print(q.pop())
print(q.is_filled())


#队列的内置模块
from collections import deque

q=deque()    #创建一个空队列
q1=deque([1,2,3,4,5],5)   #创建时已队列已有这n个元素,队列长度为5,队满后,在有元素进队时,队首自动出队
q1.append(6)
print(q1)
q.append(1)    #队尾进队
q.append(2)
print(q.popleft()) #队首出队
print(q)

'''
#用于双向列表
q.appendleft()  #队首进队
q.pop()  #队尾出队
'''

2.2队列解决迷宫问题

队列–广度优先搜索
思路:从一个节点开始,寻找–所有–接下来能走的点,继续不断寻找,指到找到出口
使用队列存储当前正在考虑的节点

代码

maze=[
    [1,1,1,1,1],
    [1,0,1,1,1],
    [1,0,0,1,1],
    [1,1,0,0,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)
]

#队列的内置模块
from collections import deque

def print_r(path):
    cur_Node=path[-1]
    real_path=[]

    while cur_Node[2]!=-1:
        real_path.append(cur_Node[0:2])
        cur_Node=path[cur_Node[2]]

    real_path.append(cur_Node[0:2])
    real_path.reverse()
    for node in real_path:
        print(node)



def maze_path(x1,y1,x2,y2):
    queue=deque()                  #创建一个队列,用于
    queue.append((x1,y1,-1))       #-1表示x1,y1是自己进来的
    path=[]                       #存放出队的节点
    while len(queue)>0:           #只要队不空,进行以下语句
        cur_Node=queue.popleft()  #队首出队,并将队首的值赋给cur_Node
        path.append(cur_Node)
        if cur_Node[0]==x2 and cur_Node[1]==y2:
            #终点
            print_r(path)
            return True
        for dir in dirs:
            next_Node=dir(cur_Node[0],cur_Node[1])
            if maze[next_Node[0]][next_Node[1]]==0:
                queue.append((next_Node[0],next_Node[1],len(path)-1))    #后续节点进队,记录那个节点带他来的
                maze[next_Node[0]][next_Node[1]]=2

    else:
        print('没有路')
        return False
maze_path(1,1,3,3)

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值