事实上,Python本身自带的列表就可以很好的实现栈的操作,当然,如果你想实现一个像链表一样的栈结构的话,可以用deque,也可以像下面这样自己写一个类。下面介绍如何在Python中创建一个栈:
class Node:
def __init__(self,value):
self.value = value #节点的值
self.next = None #指向前一个节点的指针
class Strack:
def __init__(self):
self.head = None #栈顶指针
self.length = 0 #栈中节点数量
def pop(self):
if self.head != None:
node = self.head #获取栈顶指针指向的节点
self.head = node.next #栈顶指针向下一个节点移动
node.next = None #栈顶节点的向前指针为空
self.length-=1 #节点总数减一
return node.value #返回删除的值,即弹出操作
else:
return None
def push(self,value):
node = Node(value) #将入栈的数据转化为节点
if self.head != None:
node.next = self.head #入栈的节点指向前一个节点
self.head = node #栈顶指针指向新入栈的节点
else:
self.head=node #栈顶指针指向唯一节点
self.length+=1
def isNone(self):
if self.length>0:
return False
else:
return True
需要注意的是,栈顶指针总是在栈的最上层,也就是head,向栈中加入数据时要先将数据转化为一个节点。使用时只需要实例化一个Strack对象然后调用相关方法就可以了。下面是一个简单的调用格式:
strack = Strack()
for i in range(4):
strack.push(i)
for i in range(4):
print(strack.pop())
print(strack.isNone())
最小栈:
最小栈的概念很简单,就是当前栈顶元素的值始终为栈中元素的最小值,实现方式也很简单:每次入栈时进行判断,如果小于等于栈顶元素就直接入栈,如果大于,就执行弹出操作,直至栈顶元素大于入栈元素,然后将新值入栈,将之前弹出的节点重新压入栈内。
import Node
class MinStrack:
def __init__(self):
self.head = None
self.length = 0
def push(self,value):
node = Node(value)
if self.head != None:
if node.value>self.head.value:
minval = self.pop() #弹出栈顶元素
self.add(node)
self.length+=1 #把pop减的一加回来
self.add(Node(minval))
else:
self.add(node)
else:
self.head = node
self.length+=1
def add(self,node):
node.next = self.head #新节点指向原来的栈顶
self.head = node #栈顶更新至新节点位置
def pop(self):
if self.head != None:
node = self.head
self.head = node.next
node.next = None
self.length-=1
return node.value
else:
return None
def isNone(self):
if self.length>0:
return False
else:
return True
需要注意的是,最小栈实现的仅仅是最顶部的数最小,无法对整个入栈的数据进行排序。实际上,如果你要实现栈中的数据从底向上由大到小的话,可以用两个栈实现,不过与其用两个栈不如直接将数据sort一下然后压入栈。
队列:
一种典型的FIFO数据结构,建立这种结构需要两个指针,一个指向队头,一个指向队尾。实现队列其实有两种方式,一种是数组,一种是链表。我们多用链表来实现队列,这很方便,至于为什么不用数组?当你弹出队头的元素,也就是数组下标为0的元素是,其余元素需要依次向前移动,这太低效了。
队列的实现如下所示:
class Node:
def __init__(self,value):
self.value = value #节点的值
self.next = None #指向下一个节点的指针
class DuiLie:
def __init__(self):
self.head = None #队首指针
self.end = None #队尾指针
self.length = 0
def insert(self,value):
node = Node(value)
if self.head != None:
self.end.next = node #尾指针所在的节点的next指向新节点
self.end = node #尾指针指向新节点
else:
self.head = node
self.end = node
self.length+=1
def out(self):
node = self.head
if node.next != None:
self.head = node.next
node.next = None
else: #是最后一个节点
self.head = None #头尾指针都置空
self.end = None
self.length-=1
return node.value
def isNone(self):
if self.length>0:
return False
else:
return True
与前文提到的栈不同的是,这里的next指的是下一个,而栈由于结构的原因,next的意义实际上是“上一个”。