《数据结构与算法 python语言描述》学习笔记(五)———— 栈和队列

第一部分:学习内容概要

  • 概述
  • 栈:概念和实现
  • 栈的应用
  • 队列
  • 迷宫求解和状态空间搜索

第二部分:学习笔记

  • 概述
      1. 栈是保证元素后进先出(Last In First On,LIFO)
      2. 队列是保证元素先进先出(First In First On, FIFO)
      3. 应用环境:
        计算过程分为一些顺序进行的步骤(任何复杂一点的计算都是这样)
        计算中执行的某些步骤会不断产生一些后面可能需要的中间数据
        产生的数据中有些不能立即使用,但有需要在将来使用
        需要保存的数据的项数不能事先确定

  • 栈:概念和实现
      1. 栈(Stack)是一种容器,可存入数据元素、访问元素、删除元素等。
      2. 栈的抽象数据类型

ADT Stack:
	Stack(self)		#创建空栈
	is_empty(self)		#判断栈是否为空,空时返回Ture否则返回False
	push(self,elem)		#将元素elem加入栈,也常称为压入或推入
	pop(self)		#删除栈内最后压入的元素并将其返回,常称为弹出
	top(self)		#取得栈里最后压入的元素,不删除

    3.栈的顺序表实现,后端插入和删除是O(1)操作,对于链接表,前端插入和删除都是O(1)操作。

'''栈的顺序表实现'''
class StackUnderflow(ValueError):
	pass

class SStack():
	def __init__(self):
		self._elem = []
	
	def is_empty(self):
		return self._elem == []
	
	def top(self):
		if self._elem == []:
			raise StackUnderflow("in SStack.top()")
		return self._elem[-1]
	
	def push(self, elem):
		self._elems.append(elem)
	
	def pop(self):
		if self._elems == []:
			raise StackUnderflow("in SStack.top()")
		return self._elems.pop()
'''栈的链接表实现'''
class StackUnderflow(ValueError):
	pass

class LStack():
	def __init__(self):
		self._top = None
	
	def is_empty(self):
		return self_top is None
	
	def top(self):
		if self._top is None:
			raise StackUnderflow("in LStack.top()")
		return self._top.elem
	
	def push(self, elem):
		self._top = LNode(elem, self._top)
	
	def pop(self):
		if self._top is None]:
			raise StackUnderflow("in LStack.top()")
		p = self._top
		self._top = p.next
		return p.elem
  • 栈的应用
      1. 括号匹配问题:
        ① 顺序扫描被检查正文里的一个个字符
        ② 检查中跳过无关字符
        ③ 遇到开括号时将其压入栈
        ④ 遇到闭括号是弹出当时栈顶元素与之匹配
        ⑤ 如果匹配成功则继续,发现不匹配时检查以失败结束

  2. 表达式的表示、计算和变换
    中缀形式:(3 - 5) * (6 + 17 * 4)/ 3
    前缀形式:/ * - 3 5 + 6 * 17 4 3
    后缀形式:3 5 - 6 17 4 * + * 3 /
  3. 简单背包问题

''' 括号匹配文图'''
parens = "()[]{}"
open_parens = "([{"
opposite = {
")": "(", "[": "]", "}": "{"
    }

def check_parens(text):
    parens = "()[]{}"
    open_parens = "([{"
    opposite = {
")": "(", "[": "]", "}": "{"
    }

def parentheses(text):
    i, text_len = 0, len(text)
    while True:
        while i < text_len and text[i] not in parens:
            i += 1
            if i >= text_len:
                return
            yield text[i], i
            i += 1

    st = SStack()
    for pr, i in parentheses(text):
        if pr in open_parens:
            st.push(pr)
        elif st.pop() != opposite[pr]:
            print("Unmatching is found at", i, "for", pr)
            return False
    
    print("All parentheses are correctly matched.")
    return True
'''后缀表达式'''

def suffix_exp_evaluator(line):
    return suffix_exp_evaluator(line.split())


class ESStack(SStack):
    def depth(self):
        return len(self._elems)


def suf_exp_evaluator(exp):
    operators = "+-*/"
    st = ESStack()
    
    for x in exp:
        if x not in operators:
            st.push(float(x))
            continue
            
        if st.depth() < 2:
            raise SyntaxError("Short of operand(s).")
        a = st.pop()
        b = st.pop()
        
        if x == "+":
            c = b + a 
        elif x == "-":
            c = b - a 
        elif x == "*":
            c = b * a 
        elif x == "/":
            c = b / a 
        else:
            break
        
        st.push(c)
    if st.depth():
        return st.pop()
    raise SyntaxError("Extra operand(s).")
  • 队列
      队列,或称为队,也是一种容器,可存入元素、访问元素、删除元素。
         1.队列的抽象数据类型
ADT Queue:
	Queue(self)		#创建空队列
	is_empty(self)		#判断队列是否为空
	enqueue(self, elem)	#将元素elem加入队列,常称为入队
	dequeue(self)		#删除队列里最早进入的元素并将其返回,常称为出队
	peek(self)		#查看队列里最早进入的元素,不删除

  队列类的实现

class SQueue():
    def __init__(self, init_len=8):
        self._len = init_len
        self._elems = [0] * init_len
        self._head = 0
        self._num = 0
    
    def is_empty(self):
        return self._num
    
    def peek(self):
        if self._num = 0:
            raise QueueUnderflow
        return self._elems[self._head]
    
    def dequeue(self):
        if self._num == 0:
            raise QueueUnderflow
        e = self._elems[self._head]
        self._head = (self._head+1) % self._len
        self._num -= 1
        return e
    
    def enqueue(self, e):
        if self._num == self._len:
            self.__extend()
        self._elems[(self._head+self._num) % self._len] = e
        self._num += 1
        
    def __extend(self):
        old_len = self._len
        self._len *= 2
        new_elems = [0]*self._len
        for i in range(old_len):
            new_elems[i] = self._elems[(self._head+i) % old_len]
        self._elems, self._head = new_elems, 0
  • 迷宫求解和状态空间搜索
'pos为二元序对(i, j)普通方法'

dirs = [(0, 1), (1, 0), (0, -1), (-1, 0)]

def mark(maze, pos):   #给迷宫maze的位置pos标2表示“到过了”
    maze[pos[0]][pos[1]] = 2


def passable(maze, pos):      #检查迷宫maze的位置pos时候可行
    return maze[pos[0]][pos[1]] == 0


def find_path(maze, pos, end):
    mark(maze, pos)
    if pos == end:          #已到达出口
        print(pos, end=" ")     #输出这个位置
        return True     #成功结束
    for i in range(4):      #否则按四个方向顺序探查
        nextp = pos[0] + dirs[i][0], pos[1] + dirs[i][1]
        #考虑下一个可能方向
        if passable(maze, nextp):
            if find_path(maze, nextp, end):
                print(pos, end=" ")  # 输出这个位置
                return True
    return False

'''堆栈实现'''
class StackUnderflow(ValueError):
    pass


dirs = [(0, 1), (1, 0), (0, -1), (-1, 0)]


def mark(maze, pos):   #给迷宫maze的位置pos标2表示“到过了”
    maze[pos[0]][pos[1]] = 2


def passable(maze, pos):      #检查迷宫maze的位置pos时候可行
    return maze[pos[0]][pos[1]] == 0


class SStack():
    def __init__(self):
        self._elem = []

    def is_empty(self):
        return self._elem == []

    def top(self):
        if self._elem == []:
            raise StackUnderflow("in SStack.top()")
        return self._elem[-1]

    def push(self, elem):
        self._elems.append(elem)

    def pop(self):
        if self._elems == []:
            raise StackUnderflow("in SStack.top()")
        return self._elems.pop()


def maze_solver(maze, start, end):
    if start == end:
        print(start)
        return
    st = SStack()
    mark(maze, start)

    st.push((start, 0))
    while not st.is_empty():
        pos, nxt = st.pop()
        for i in range(nxt, 4):
            nextp = (pos[0] + dirs[i][0],
                     pos[1] + dirs[i][1])
            if nextp == end:
                print("maze end")
                return
            if passable(maze, nextp):
                st.push((pos, i+1))
                mark(maze, nextp)
                st.push((nextp, 0))
                break
    print("No path found.")
  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值