兄弟萌,话不多说,show me the code!
Assoc类:
class Assoc:
def __init__(self,key,value):
self.key = key
self.value = value
def __lt__(self, other):
"""有时有些操作需要考虑排序"""
return self.key < other.key
def __le__(self, other):
return self.key < other.key or self.key == other.key
def __str__(self):
"""定义字符串表示形式便于输出和交互"""
return f"Assoc({self.key},{self.value})"
SStack类:
"""栈的顺序表实现"""
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()
from chapter8.Assoc import Assoc
from stack_queue.code import SStack
def btSearch(btree,key):
"""二叉排序树的检索算法"""
bt = btree
while bt != None:
entry = bt.data
if key < entry.key:
bt = bt.left
elif key > entry.key:
bt = bt.right
else: # key == entry.key
return entry.value # 返回关键码的关联值
# 走完整棵树仍没有找到
return None
class BinTNode:
"""树节点类"""
def __init__(self,dat,left=None,right=None):
self.data = dat
self.left = left
self.right = right
class DictBinTree:
"""字典二叉排序树类"""
def __init__(self):
self._root = None
def isEmpty(self):
"""判断是否为空"""
return self._root is None
def search(self,key):
"""检索"""
bt = self._root
while bt != None:
entry = bt.data
if key < entry.key:
bt = bt.left
elif key > entry.key:
bt = bt.right
else: # key == entry.key
return entry.value # 返回关键码的关联值
# 走完整棵树仍没有找到
return None
def insert(self,key,value):
bt = self._root
if bt == None:
"""如果树为空,直接建立一个新关键码和关联值的树根节点"""
self._root = BinTNode(Assoc(key,value))
return
"""否则搜索新节点的插入位置,沿子节点关系向下"""
while True:
entry = bt.data
if key < entry.key:
"""遇到应该走左子树"""
if bt.left == None:
"""而左子树为空"""
bt.left = BinTNode(Assoc(key,value))
return
bt = bt.left
elif key > entry.key:
"""遇到应该走右子树"""
if bt.right == None:
"""而右子树为空"""
bt.right = BinTNode(Assoc(key,value))
return
return bt.right
else:
"""碰到值相等"""
bt.data.value = value
return
def values(self):
"""中序遍历,值生成迭代器"""
t,s = self._root,SStack()
while t != None or not s.is_empty():
while t != None:
s.push(t)
t = t.left
t = s.pop()
yield t.data.key, t.data.value
t = t.right
def delete(self,key):
"""删除节点,保证树的结构不变"""
p,q = None, self._root # 维持p为q的父节点 ,从树根开始找q
while q != None and q.data.key != key:
p = q # 维持p为q的父节点
if key < q.data.key:
q = q.left
else:
q = q.right
if q is None:
return # 树中没有关键码key
"""到这里q引用要删除节点,p是其父节点或None(这时q是根节点)"""
if q.left == None:
"""q没有左子节点"""
if p == None:
"""q是根节点,直接修改root"""
self._root = q.right
elif q == p.left:
p.left = q.right
else:
p.right = q.right
return
r = q.left
while r.right != None:
r = r.right
r.right = q.right
if p == None:
"""q是根节点,修改_root"""
self._root = q.left
elif p.left == q:
p.left = q.left
else:
p.right =q.left
def print(self):
for k,v in self.entries():
print(k,v)
def buildDictBinTree(entries):
dic = DictBinTree()
for k,v in entries:
dic.insert(k,v)
return dic
class DictOptBinTree(DictBinTree):
def __init__(self,seq):
DictBinTree.__init__(self)
data = sorted(seq)
self._root = DictOptBinTree.buildOBT(data,0,len(data)-1)
@staticmethod
def buildOBT(data,start,end):
if start > end:
return None
mid = (end+start)//2
left = DictOptBinTree.buildOBT(data,start,mid-1)
right = DictOptBinTree.buildOBT(data,mid+1,end)
return BinTNode(Assoc(*data[mid],left,right))