栈
先设置栈下溢异常
class StackUnderflow(ValueError): # 栈下溢
pass
栈的顺序表实现
class SStack(): # 基于顺序表技术实现的栈类
def __init__(self): # 用list对象 _elems存储栈中元素
self._elems = [] # 所有栈操作都映射到list的操作
def is_empty(self):
return self._elems == []
def top(self):
if self._elems == []
raise StackUnderflow("in SStack.top()")
return self._elems[-1]
def push(self, elem):
self._elems.append(elem)
def pop(self):
if self._elems == []
raise StackUnderflow("in SStack.pop()")
return self._elems.pop()
栈的链接表实现
class LNode:
def __init__(self, elem, next_ = None):
self.elem = elem
self.next = next_
class LStack(): # 基于链接表技术实现的栈类, 用LNode作为节点
def __init__(self):
self._top = None
def is_empty(self):
return self._top == 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.pop()")
p = self._top
self._top = p.next
return p.elem
栈的应用: 简单背包问题
"""
一个背包可放入重量为weight的物品, 现有n件物品的集合S, 其中物品的重量分别为w0, w1,...,wn-1
问题是能否从中选出若干件物品,其重量之和正好等于weight。如果存在说明有解,否则无解。
"""
def knap_rec(weight, wlist, n):
if weight == 0:
return True
if weight < 0 or (weight > 0 and n < 1):
return False
if knap_rec(weight - wlist[n-1], wlist, n-1):
print("Item " + str(n) + ":", wlist[n-1])
return True
if knap_rec(weight, wlist, n-1):
return True
else:
return False
队列
队列的list实现
队列的首元素在self._elems[self._head], peek 和 dequeue操作应该取这里的元素;下一个空位在self._elems[(self._head + self._num) % self._len], 入队的新元素应该存放在这里。
另外,队列空就是self._num = = 0, 当前队列满就是self._num == self._len, 这个条件成立时应该换一块存储区。
class QueueUnderflow(ValueError):
pass
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 == 0
def peek(self):
if self._num == 0:
raise QueueUnderflow("in peek")
return self._elems[self._head]
def dequeue(self):
if self._num == 0:
raise QueueUnderflow("in dequeue")
e = self._elems[self._head]
self._head = (self._head+1) % self._len
self._num -= 1
return e
def enqueue(self):
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