栈
栈(Stack)是一个数据集合,可以理解为只能在一段进行插入或删除的列表.
特点
LIFO(last_in, first_out),栈中的数据后进先出
栈的相关概念
栈顶,栈底
栈的基本操作
(1)进栈:push
(2)出栈:pop
(3)取栈顶元素:peek()
(4)检查栈是否为空:isEmpty()
(5)检查栈的大小:size()
栈的实现
栈可以使用列表来实现,以下我代码,(也可直接使用列表当栈)
class Stack():
def __init__(self):
self.stack = []
def isEmpty(self):
return self.stack == []
def size(self):
return len(self.stack)
def push(self, val):
return self.stack.append(val)
def pop(self):
return self.stack.pop()
def peek(self):
if self.size():
return self.stack[-1]
else:
return None
栈的使用
接下来看几个小例子感受下栈的特点
(1)括号的匹配
判断字符串中的括号是否匹配
思路:
当括号是左括号时我们就将其放入栈中,当遇到右括号时,我们就查看栈顶的元素是不是与其匹配的左括号,如果匹配则将这个左括号出栈;如果不匹配则括号不匹配.因为左边离第一个右括号最近的左括号必定是匹配的.
def match_brace(strval):
stack = Stack()
match_dict = {')': '(', '}': '{', ']': '['}
for i in strval:
if i in '[({':
stack.push(i)
else:
if stack.isEmpty():
return False
else:
if stack.peek() == match_dict[i]:
stack.pop()
else:
return False
if stack.isEmpty():
return True
else:
return False
(2)进制转换
将十进制的数转换成其他进制,是将给定的十进制除以进制然后得到余数,计算出的第一个数是最后一位,依次类推.
代码实现如下:
def divideBy(num, base):
'''
将十进制数转换成任意进制
:param num: 十进制的数
:param base: 进制
:return:
'''
digits = '0123456789ABCDEF'
stack = Stack()
while num:
rem = num % base
stack.push(rem)
num = num // base
new_str = ''
while not stack.isEmpty():
new_str = new_str + digits[stack.pop()]
return new_str
栈–深度优先(迷宫问题)
深度优先又名回溯法.
思路:从一个节点开始,任意找下一个能走的点,当找不到能走的点时,退回上一个点寻找其他方向的点.
这样的话我们用栈来存储当前的路径
如图:
代码实现:
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],
]
# 当前点想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_stack(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 node in stack:
print(node)
return
# 向四个方向寻找路径:
for dir in dirs:
nextNode = dir(curNode[0],curNode[1])
if maze[nextNode[0]][nextNode[1]] == 0:
stack.append(nextNode)
maze[nextNode[0]][nextNode[1]] = 2
break
else:
# 如果四个方向都没找到路径,则向上回溯
maze[curNode[0]][curNode[1]] = 2
stack.pop()
maze_stack(1,1,8,8)