python算法--栈与队列

这一节主要讲述栈和队列,这两种数据结构使用python的实现,并且讲述了这两种数据结构的常见问题和方法。

栈的实现

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

    def isEmpty(self):
        return self.item==[]

    def push(self,i):
        self.item.append(i)

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

    def peek(self):
        return self.item[len(self.item)-1]

    def size(self):
        return len(self.item)

​ 使用python里面的列表来实现一个栈的数据结构,实现的主要功能包括:

1、长度

2、是否为空

3、添加元素

4、推出栈尾元素

5、peek。显示队尾元素,不推出。

​ 主要功能是 添加+推出 元素,直接使用python列表的append函数和pop函数即可,较为简单。

: 这里有一点编程时容易错的,size在类中是一个函数,所以每次调用时需要使用s.size(),很多时候容易犯错写成s.size,就比较容易错。

队列的实现

class Queue:

    def __init__(self):
        self.item=[]

    def isEmpty(self):
        return self.item==[]

    def enqueue(self,x):
        self.item.insert(0,x)

    def dequeue(self):
        return self.item.pop()

    def size(self):
        return len(self.item)

​ 同样使用python的列表来实现队列。主要功能还是针对 添加元素推出元素:因为队列先进先出的特点,所以没有栈结构那么直接,推出元素还是使用pop,那么添加元素就需要从队首添加,于是可以使用insert函数:

def enqueue(self,x):
	self.item.insert(0,x)

其余的功能函数实现方法就和栈差不多了。

经典应用场景

下面介绍几个栈和队列数据结构解决问题的经典案例

问题一:括号匹配

描述:假设在一段字符串中,有如下几种括号<> () [] {},如果想要符合语义,每一个左括号需要在合适的位置对应一个右括号。给定一段充满括号的字符串,判断是否其中的括号是否是平衡的。

实现

def isBrakectsMatch(givenstr):
    s=Stack()
    LeftBrakects=['<','(','[','{']
    RightBrakects=['>',')',']','}']
    for i in givenstr:
        if i in LeftBrakects:
            s.push(i)
        elif i in RightBrakects:
            if s.size()==0:
                return False
            else:
                if LeftBrakects.index(s.pop())!=RightBrakects.index(i):
                    return False
                else:
                    pass
        else:
            pass

    if s.size() == 0:
        return True
    else:
        return False

核心思想:扫描这段字符串,如果碰到左括号,就压入栈中;如果碰到右括号,就用它和栈中推出的末端元素比对。最后扫描完字符串,栈中无元素,则匹配。若不是,或者中间匹配时无法对得上,则不匹配。

细节点:

(1)碰到右括号比对时,先把左右括号放在两个闲置的列表中,然后用列表的index进行比对;

(2)栈数据结构的长度,使用s.size(),括号不能少,否则程序出错。

问题二:表达式转换

背景知识:中缀表达式就是运算符在中间的表达式,数学中都是这种。运算中有所谓的运算优先级,比如是乘除优先于加减。为了方便计算机能够识别优先级,引入了全括号表达式:以最里面的括号为最优先。

前缀表达式和后缀表达式,就是把表达符放在前面或者后面。前后缀表达式的一个优点是不需要注意优先级,且不需要括号,就可以直接按正确的顺序进行运算。前后缀表达式和全括号表达式的转换规则如下:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-yop4a5El-1598376573912)(C:\Users\wangzihao\AppData\Roaming\Typora\typora-user-images\image-20200823041843174.png)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-75G7bytw-1598376573915)(C:\Users\wangzihao\AppData\Roaming\Typora\typora-user-images\image-20200823041940801.png)]

描述:将正常的中缀表达式转换成相应的前缀表达式和后缀表达式。以及如何转换回来?(通用算法)

def Middle2After(expressionStr):
    s=Stack()
    strList = expressionStr.split(' ')
    outList=[]
    markvalue={'+':1,'-':1,'*':2,'/':2,'(':0}
    for i in strList:

        if i == '(':
            s.push(i)
        elif i ==')':
            temp=s.pop()
            while temp!='(':
                outList.append(temp)
                temp=s.pop()
        elif i in markvalue:
            while s.size()!=0 and markvalue[s.peek()]>markvalue[i]:
                outList.append(s.pop())
            else:
                s.push(i)
        else:
            outList.append(i)

    while s.size()!=0:
        outList.append(s.pop())

    return outList

实现的核心逻辑如下:

1、先划分出运算符的自然权重,乘除较高,加减较低,后面做比较;

markvalue={'+':1,'-':1,'*':2,'/':2,'(':0}

2、遇到运算符,先压进栈。只有当栈顶的运算符确实比下面那个高的时候,才能够输出这个栈顶运算符;

3、括号权限较重,所以遇到左括号时先压进栈,遇到右括号时,把栈中一直到左括号的运算符全部输出来。

问题三:热土豆问题

描述:有M个土豆围成一圈,从1编号到M,然后从1开始,每n个土豆就拿一个去加热吃掉,问最后留下来的那个土豆是一开始在哪个编号上的?

实现代码

def HotTomato(m,n):
    q=Queue()
    for i in range(1,m+1):
        q.enqueue(i)
    num=1
    while q.size()!=1:
        temp=q.dequeue()
        if num%n!=0:
            q.enqueue(temp)
        num=num+1
    return q.dequeue()

细节讲解:

1、核心思想一目了然,全部放到队列里,然后每次推一个再进一个,除非这个是n的倍数(即拿去加热);

2、函数暂时没有考虑M,N数值非法的情况,默认是OK的

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值