栈(Python实现)
一、什么是栈
栈是一种有序的集合,添加操作和移除操作总发生在同一端。
栈最大的特点是先进后出,最新添加的元素将被最先移除,这种排序原则被称为 LIFO(last-in first-out),后进先出。
例如我们在课桌上放的书本:
当然这只是一种模拟,实际中你当然可以直接抱起上面一叠书,直接取出语文书。还有我们在操作Word文档时也有栈的身影,我们在文档中所操作的每一步都会被压入栈中,你按个Ctrl+Z就会返回上一步的操作,再按再返回,越早的操作越往后才返回。
观察上图可以发现最先被放入的书本最后被取出,如果取出时按顺序保存,那么是不是就变成了化学在最下面,语文在最上面,也就是说栈可以反转元素的排列顺序。
二、栈抽象数据类型
所谓抽象数据类型就是栈是我们抽象出来的一种数据类型,本身并没有它。比如C语言中会有int类型,float类型,但不会有个stack(栈)类型吧。
栈抽象数据类型有下面的结构和操作定义:
1.Stack() 创建一个空栈。它不需要参数,且会返回一个空栈。
2.push() 将一个元素添加到栈的顶端。它需要一个参数item,且无返回值。
3.pop() 将栈顶端的元素移除。它不需要参数,但会返回顶端的元素,并且修改栈的内容。
4.peek() 返回栈顶端的元素,但是并不移除该元素。它不需要参数,也不会修改栈的内容。
5.isEmpty() 检查栈是否为空。它不需要参数,且返回一个布尔值。
6.size() 返回栈中元素的数目。它不需要参数,且会返回一个整数。
三、Python实现
和其它面向对象编程语言一样,每当需要在Python中实现像栈这样的抽象数据类型时,就可以创建新类。栈的操作通过方法实现。更进一步的说,因为栈是元素的集合,所以完全可以利用Python提供的强大、简单的原生集合来实现。我一般都会选择列表来实现。
首先要确定列表的哪一边作为栈的顶端。一旦确定了顶端,所有的操作就可以利用append和pop等列表方法来实现。这里我选择列表的末尾作为栈的顶端,所以用append()方法压栈,你也可以尝试用列表的前端最为栈的顶端来实现栈。
代码(文件名为 Stack.py):
class Stack: def __init__(self): self.item = [] def push(self, value): self.item.append(value) def pop(self): return self.item.pop() def peek(self): return self.item[len(self.item)-1] def size(self): return len(self.item) def isEmpty(self): return self.item == []
四、栈的运用:匹配括号
匹配括号是指每一个左括号都有与之对应的一个右括号,并且括号对有正确的嵌套关系,如:(()()()()) 、((()()))。不匹配的像:(((((()))、())))。我们的任务就是编写一个算法,他从左到右读取一个括号串,然后判断其中的括号是否匹配。
想法:由一个空栈开始,从左往右依次处理括号。如果遇到左括号,便通过push操作将其压入栈中,以此表示稍后需要有一个与之匹配的右括号。如果遇到右括号,就调用pop操作。只要栈中的所有左括号都能遇到与之匹配的右括号,那么整个括号串就是匹配的,即栈就会为空。反之则不然。
例如:((()))() "(":push() "(":push() "(":push() ")":pop() ")":pop() ")":pop() "(":push() ")":pop() 这样括号正确匹配的会使最后的栈为空。
代码(文件名为 parChecker.py):
from Stack import * def parChecker(symblstring): s = Stack() for i in range(len(symblstring)): if symblstring[i] == "(": s.push(symblstring[i]) else: s.pop() if s.isEmpty(): return True else: return False
五、练习
1,匹配符号
和上面的类似,如:{{(([][])}()} [[{{(())}}]] [][][](){} 不匹配的:([)] ((()])) [{()]
2.利用栈实现将十进制数转换为二进制数;再改写程序实现将十进制数转换为任意进制数。