用链表实现
class BinaryTree:
def __init__(self,root):
self.key=root
self.left=None
self.right = None
def insertleft(self,newnode):
if self.left is None:
self.left=BinaryTree(newnode)
else:
t=BinaryTree(newnode)
t.left = self.left
self.left=t
def insertright(self,newnode):
if self.right is None:
self.right=BinaryTree(newnode)
else:
t=BinaryTree(newnode)
t.right = self.right
self.right=t
def getright(self):
return self.right
def getleft(self):
return self.left
def setval(self, val):
self.key=val
def getval(self):
return self.key
r=BinaryTree('a')
r.insertright('b')
r.insertleft('b')
r.getright().setval('hello')
r.getleft().insertright('d')
完全二叉树列表表示
如果节点的下标为p,那么其左子节点下标为2p, 右子节点为2p+1,其父节点下标为p//2
表达式解析
前序遍历(preorder) : 先访问根节点,再递 归地前序访问左子树、最后前序访问右子树;
中序遍历(inorder) : 先递归地中序访问左子 树,再访问根节点,最后中序访问右子树;
后序遍历(postorder) : 先递归地后序访问左 & ( 先序 子树,再后序访问右子树,最后访问根节点。
遍历
class BinaryTree:
def __init__(self,root):
self.key=root
self.left=None
self.right = None
def insertleft(self,newnode):
if self.left is None:
self.left=BinaryTree(newnode)
else:
t=BinaryTree(newnode)
t.left = self.left
self.left=t
def insertright(self,newnode):
if self.right is None:
self.right=BinaryTree(newnode)
else:
t=BinaryTree(newnode)
t.right = self.right
self.right=t
def getright(self):
return self.right
def getleft(self):
return self.left
def setval(self, val):
self.key=val
def getval(self):
return self.key
def preorder(tree):
if tree:
print(tree.getval())
preorder(tree.getleft())
preorder(tree.getright())
def posorder(tree):
if tree !=None:
posorder(tree.getleft())
posorder(tree.getright())
print(tree.getval())
def inorder(tree):
if tree !=None:
inorder(tree.getleft())
print(tree.getval())
inorder(tree.getright())
r=BinaryTree('a')
r.insertright('b')
r.insertleft('b')
r.getright().setval('hello')
r.getleft().insertright('d')
preorder(r)
print()
posorder(r)
print()
inorder(r)
def postval(tree):#后续遍历表达式求值
if tree:
res1=postval(tree.getleft())
res2=postval(tree.getright())
return eval(res1+tree.getval+res2)
def printexp(tree):
sval=''
if tree:
sval='('+printexp(tree.getleft())
sval=sval+str(tree.getval())
sval=sval+printexp(tree.getright())+')'
return sval
postval(r)
优先队列与二叉堆
from pythonds.trees.binheap import BinHeap
bh=BinHeap()
bh.insert(5)
bh.insert(7)
bh.insert(15)
bh.insert(52)
print(bh.delMin())
print(bh.delMin())
print(bh.delMin())
print(bh.delMin())
5
7
15
52
堆次序
二叉堆基本命令
from pythonds.trees.binheap import BinHeap
从无序表生成堆
buildHeap(alist)
插入元素
insert(k)
返回最小元素,并删除
delMin()
堆排序
优先散列表,再avl树
BinaryTree()创建一个二叉树实例。
getLeftChild()返回当前节点的左子节点所对应的二叉树。
getRightChild()返回当前节点的右子节点所对应的二叉树。
setRootVal(val)在当前节点中存储参数 val 中的对象。
getRootVal()返回当前节点存储的对象。
insertLeft(val)新建一棵二叉树,并将其作为当前节点的左子节点。
insertRight(val)新建一棵二叉树,并将其作为当前节点的右子节点。
实现树的关键在于选择一个好的内部存储技巧。
Python 提供两种有意思的方式,我们在选择
前会仔细了解这两种方式。第一种称作“列表之列表”,第二种称作“节点与引用”。
术语及定义
- 节点
节点是树的基础部分。它可以有自己的名字,我们称作“键”。节点也可以带有附加信息,
我们称作“有效载荷”。有效载荷信息对于很多树算法来说不是重点,但它常常在使用树的应用
中很重要。
- 边
边是树的另一个基础部分。两个节点通过一条边相连,表示它们之间存在关系。除了根节点
以外,其他每个节点都仅有一条入边,出边则可能有多条。
- 根节点
根节点是树中唯一没有入边的节点。在图 6-2 中,/就是根节点。
- 路径
路径是由边连接的有序节点列表。比如,哺乳纲→食肉目→猫科→猫属→家猫就是一条路径。
- 子节点
一个节点通过出边与子节点相连。在图 6-2 中,log/、spool/和 yp/都是 var/的子节点。
- 父节点
一个节点是其所有子节点的父节点。在图 6-2 中,var/是 log/、spool/和 yp/的父节点。
- 兄弟节点
具有同一父节点的节点互称为兄弟节点。文件系统树中的 etc/和 usr/就是兄弟节点。
子树
一个父节点及其所有后代的节点和边构成一棵子树。
- 叶子节点
叶子节点没有子节点。比如,图 6-1 中的人和黑猩猩都是叶子节点。
- 层数
节点 n 的层数是从根节点到 n 的唯一路径长度。在图 6-1 中,猫属的层数是 5。由定义可知,
根节点的层数是 0。
- 高度
树的高度是其中节点层数的最大值。图 6-2 中的树高度为 2。
用列表实现
def BinaryTree(r):#列表函数
return [r, [], []]
def insertLeft(root, newBranch):#插入左子树
t = root.pop(1)
if len(t) > 1:
root.insert(1, [newBranch, t, []])
else:
root.insert(1, [newBranch, [], []])
return root
def insertRight(root, newBranch): #插入右子树
t = root.pop(2)
if len(t) > 1:
root.insert(2, [newBranch, [], t])
else:
root.insert(2, [newBranch, [], []])
return root
def getRootVal(root):#树的访问函数
return root[0]
def setRootVal(root, newVal):
root[0] = newVal
def getLeftChild(root):
return root[1]
def getRightChild(root):
return root[2]