一、用列表模拟栈
栈并不是python的内建类型,可以通过使用list来模拟栈,将列表的末尾看做栈的顶。用这种方法的主要缺点是:所有其他的列表操作也可以操作这个栈,包括任意位置插入、替换和删除元素,这些操作就违反了栈作为一种抽象数据类型的本意。
1.1 栈方法:
栈方法 | 作用 |
s.isEmpty() | 如果为空,返回True,否则返回False |
s.size() | 返回s中项目的数目 |
s.iter() | 从底部到顶部,访问s中的每一项 |
s.push(item) | 在s的顶部添加一项 |
s.pop() | 在s的顶部删除一项,并返回该项。先验条件:s必须不为空,如果栈为空,将抛出KeyError |
s.peek() | 返回s的顶部的项,先验条件:s必须不为空,如果栈为空,将抛出KeyError |
s.clear() | 将s清空 |
1.2 用列表模拟栈的实现代码:
#用列表模拟栈
class Stack:
"""A list_based stack implementation."""
# Constructor
def __init__(self):
"""Sets the initial state of self,and the initial state is []"""
self.items = []
# Accessor methods
def iter(self):
"""Supports iteration over a view of self.
Visits items from bottom to top of stack."""
for i in range(len(self.items)):
yield self.items[i]
def isEmpty(self):
"""Returns True if len(self) == 0, or False otherwise."""
return len(self.items)==0
def peek(self):
"""
Returns the item at the top of the stack.
Precondition: the stack is not empty.
Raises: KeyError if the stack is empty."""
if self.isEmpty():
raise KeyError("The stack is empty.")
return self.items[len(self.items)-1]
def size(self):
"""return the len(self)"""
return len(self.items)
# Mutator methods
def clear(self):
"""Makes self become empty."""
self.items = []
def push(self, item):
"""Adds item to the top of the stack."""
self.items.append(item)
def pop(self):
"""
Removes and returns the item at the top of the stack.
Precondition: the stack is not empty.
Raises: KeyError if the stack is empty.
Postcondition: the top item is removed from the stack."""
if self.isEmpty():
raise KeyError("The stack is empty.")
return self.items.pop()
1.3 栈操作效果
#测试
if __name__=='__main__':
s=Stack() #创建一个空栈
s.push('a')
s.push('b')
s.push('c')
print(list(s.iter())) #return:['a', 'b', 'c']
print(s.size()) #return:3
print(s.pop()) #return:c
print(s.peek()) #return:b
print(s.pop()) #return:b
print(s.pop()) #return:a
#若在此处添加一句:s.pop()或s.peek(),将报错:"The stack is empty."
s.clear()
print(s.isEmpty()) #return:True
二、利用链表实现栈
2.1创建一个抽象集合类,并保存为abstractcollection.py文件
class AbstractCollection(object):
"""An abstract collection implementation."""
# Constructor
def __init__(self, sourceCollection = None):
"""Sets the initial state of self, which includes the
contents of sourceCollection, if it's present."""
self._size = 0
if sourceCollection:
for item in sourceCollection:
self.add(item)
# Accessor methods
def isEmpty(self):
"""Returns True if len(self) == 0, or False otherwise."""
return len(self) == 0
def __len__(self):
"""Returns the number of items in self."""
return self._size
def __str__(self):
"""Returns the string representation of self."""
return "[" + ", ".join(map(str, self)) + "]"
def __add__(self, other):
"""Returns a new bag containing the contents
of self and other."""
result = type(self)(self)
for item in other:
result.add(item)
return result
def __eq__(self, other):
"""Returns True if self equals other,
or False otherwise."""
if self is other: return True
if type(self) != type(other) or \
len(self) != len(other):
return False
otherIter = iter(other)
for item in self:
if item != next(otherIter):
return False
return True
2.2 创建一个抽象栈类,保存为abstractstack.py
from abstractcollection import AbstractCollection
class AbstractStack(AbstractCollection):
"""An abstract stack implementation."""
# Constructor
def __init__(self, sourceCollection = None):
"""Sets the initial state of self, which includes the
contents of sourceCollection, if it's present."""
AbstractCollection.__init__(self, sourceCollection)
# Mutator methods
def add(self, item):
"""Adds item to self."""
self.push(item)
2.3 创建一个节点类,保存为node.py
class Node(object):
"""Represents a singly linked node."""
def __init__(self, data, next = None):
self.data = data
self.next = next
2.4 用链表实现栈,保存为linkedstack.py
from node import Node
from abstractstack import AbstractStack
class LinkedStack(AbstractStack):
"""A link-based stack implementation."""
# Constructor
def __init__(self, sourceCollection = None):
"""Sets the initial state of self, which includes the
contents of sourceCollection, if it's present."""
self._items = None
AbstractStack.__init__(self, sourceCollection)
# Accessor methods
def __iter__(self):
"""Supports iteration over a view of self.
Visits items from bottom to top of stack."""
def visitNodes(node):
"""Adds items to tempList from tail to head."""
if not node is None:
visitNodes(node.next)
tempList.append(node.data)
tempList = list()
visitNodes(self._items)
return iter(tempList)
def peek(self):
"""
Returns the item at the top of the stack.
Precondition: the stack is not empty.
Raises: KeyError if the stack is empty."""
if self.isEmpty():
raise KeyError("The stack is empty.")
return self._items.data
# Mutator methods
def clear(self):
"""Makes self become empty."""
self._size = 0
self._items = None
def push(self, item):
"""Adds item to the top of the stack."""
self._items = Node(item, self._items)
self._size += 1
def pop(self):
"""
Removes and returns the item at the top of the stack.
Precondition: the stack is not empty.
Raises: KeyError if the stack is empty.
Postcondition: the top item is removed from the stack."""
if self.isEmpty():
raise KeyError("The stack is empty.")
data = self._items.data
self._items = self._items.next
self._size -= 1
return data
三、用数组实现栈
3.1 创建一个数组类,保存为arrays.py
"""
File: arrays.py
An Array is a restricted list whose clients can use
only [], len, iter, and str.
To instantiate, use
= array(, )
The fill value is None by default.
"""
class Array(object):
"""Represents an array."""
def __init__(self, capacity, fillValue = None):
"""Capacity is the static size of the array.
fillValue is placed at each position."""
self._items = list()
for count in range(capacity):
self._items.append(fillValue)
def __len__(self):
"""-> The capacity of the array."""
return len(self._items)
def __str__(self):
"""-> The string representation of the array."""
return str(self._items)
def __iter__(self):
"""Supports iteration over a view of an array."""
return iter(self._items)
def __getitem__(self, index):
"""Subscript operator for access at index."""
return self._items[index]
def __setitem__(self, index, newItem):
"""Subscript operator for replacement at index."""
self._items[index] = newItem
3.2 创建一个抽象栈类,保存为abstractstack.py (同上)
3.3用数组实现栈,保存为arraystack.py
from arrays import Array
from abstractstack import AbstractStack
class ArrayStack(AbstractStack):
"""An array-based stack implementation."""
# Class variable
DEFAULT_CAPACITY = 10
# Constructor
def __init__(self, sourceCollection = None):
"""Sets the initial state of self, which includes the
contents of sourceCollection, if it's present."""
self._items = Array(ArrayStack.DEFAULT_CAPACITY)
AbstractStack.__init__(self, sourceCollection)
# Accessor methods
def __iter__(self):
"""Supports iteration over a view of self.
Visits items from bottom to top of stack."""
cursor = 0
while cursor < len(self):
yield self._items[cursor]
cursor += 1
def peek(self):
"""Returns the item at the top of the stack.
Precondition: the stack is not empty.
Raises: KeyError if stack is empty."""
if self.isEmpty():
raise KeyError("The stack is empty")
return self._items[len(self) - 1]
# Mutator methods
def clear(self):
"""Makes self become empty."""
self._size = 0
self._items = Array(ArrayStack.DEFAULT_CAPACITY)
def push(self, item):
"""Inserts item at top of the stack."""
# Resize array here if necessary
self._items[len(self)] = item
self._size += 1
def pop(self):
"""Removes and returns the item at the top of the stack.
Precondition: the stack is not empty.
Raises: KeyError if stack is empty.
Postcondition: the top item is removed from the stack."""
if self.isEmpty():
raise KeyError("The stack is empty")
oldItem = self._items[len(self) - 1]
self._size -= 1
# Resize the array here if necessary
return oldItem
四、测试链表栈或数组栈
from arraystack import ArrayStack
from linkedstack import LinkedStack
def test(stackType):
# Test any implementation with same code
s = stackType()
print("Length:", len(s))
print("Empty:", s.isEmpty())
print("Push 1-10")
for i in range(10):
s.push(i + 1)
print("Peeking:", s.peek())
print("Items (bottom to top):", s)
print("Length:", len(s))
print("Empty:", s.isEmpty())
theClone = stackType(s)
print("Items in clone (bottom to top):", theClone)
theClone.clear()
print("Length of clone after clear:", len(theClone))
print("Push 11")
s.push(11)
print("Popping items (top to bottom): ", end="")
while not s.isEmpty(): print(s.pop(), end=" ")
print("\nLength:", len(s))
print("Empty:", s.isEmpty())
#test(ArrayStack)
test(LinkedStack)
链表和数组实现的栈比列表实现的栈要更加严格。