树的定义:
一个或多个节点组成的,除树根外,其余节点可分为n>=0个互斥的集合。其中每个子集合也是一种树形结构。节点可互联但不能构成无出口的回路。不能是空集合
森林:
n个互斥树组成森林
度数:
每个节点的所有子树的个数
层数:
以根节点为第一层向下,节点所在层数
高度:
树的最大层数
树叶或终端节点:
度数为零的节点
祖先和子孙节点
祖先节点是该节点向上的任意节点,子孙节点是向下的所有节点
非终端节点
树叶节点以外的节点
同代:
树中层数相同的节点
二叉树概念:
二叉树可以是空集合,节点的度数必须0<=d<=2
二叉树的子树之间是有次序关系的
组成结构(字段):右指针 数据 左指针
使用二叉树的原因
电脑中树一般以链表形式存储,对于n叉树(n-way树),必须为每个节点预留n个链接字段的存储空间:数据 指针 指针 指针 空 空 ... 指针n
设:n叉树有m个节点,树共有m*n个字段,另外除树根外每个非空链接都会指向一个节点所以空连接字段个数为m*n-(m-1)=m*(n-1)+1#m-1个非空节点#那么n叉树的浪费率为:(m*(n-1)+1)/(m*n)。2叉树是1/2,3叉树是2/3。这个值会越来愈大,所以说n叉树的浪费会愈来愈大
任意二叉树下:
终端节点数为n0,度数为2的节点数为n2,有:n0=n2+1
解:设总结点数为n,度数为1的节点数为n1有:n=n0+n1+n2
设分支总数为B,则n=B+1,分支B为分支为1的节点数和分支为2的节点数的和,有:B=n1+2n2,
综上有:n=n1+2n2+1,那么n1+2n2+1=n0+n1+n2,最后有n0=n2+1
树的最大节点数:
高度为k的二叉树总结点数最大为2的k次方减一###满二叉树的情况下数组求和
层数为i的节点数最多为2的(i-1)次方
满二叉树
二叉树高度为h,树的节点为2的h次方减1
有:每一层都有2的i次方减1个节点
节点数小于2的i次方减1,节点排列和满二叉树一样从左到右从上到下
特点:设n个节点的完全二叉树层数为log2的(n+1)次方取最大整数
二叉树完全没有左节点或是右节点
严格二叉树
每一个非终端节点均有非空的左右子树
二叉树的存储方式
一维数组的方式#二叉查找树:实际上是把二叉树填满空间为完全二叉树来存储
左子树的索引值是父节点索引值*2
右子树的索引值是父节点索引值*2+1
btree=[0]*16
data=[]
length=9
def btree_creat(btree,data,length)
for i in range(1,length):
level=1
while btree[level] !=0:#存放数据数组当前有值的节点下存放也就是该节点是父节点存的是子节点
if data[i]>btree[level]:#数组内的值大于树根往右子树比较
level=level*2+1
else: #数组内的值小于或等于树根往左子树比较
level=level*2
btree[level]=data[i]#直到第一个 btree[level]为零赋值,level是已经发生变化的
链表表示法:#增加和删除比较容易,相应的位置改变指针指向就好了。数组了则需要大量修改索引,会增加遍历次数。
class tree:#建立节点模型
def __init__(self):
self.data=0
self.right=None
self.left=None
def create_tree(root,val):
newnode=tree()#建立新节点指针指向None
newnode.data=val
newnode.right=None
newnode.left= None
if root==None:#确认根节点
root=newnode
return root
else:
current=root#父节点
while current !=None:
backup=current#尾节点
if current.data>val:#父节点的值大于当前节点值,则当前节点是父节点的左节点
current=current.left
else:
current=current.right#否则就是右节点
#把尾节点和当前节点值比较,更换尾节点
if backup.data>val:
backup.left=newnode
else:
backup.right=newnode
return root
data=[5,6,24,8,12,3,17,1,9]
#遍历左右分支
# 1,3,5,6,8,9,12,17,24
ptr=None
root=None
for i in range(9):
ptr=create_tree(ptr,data[i])
print("!!!!!!!")
root=ptr.left
while root !=None:
print('%d'%root.data)
root=root.left
print("###########")
root=ptr.right
while root !=None:
print('%d'%root.data)
root=root.right
二叉树的遍历:
中序遍历:左子树 树根 右子树
前序遍历:树根 左子树 右子树
后序遍历:左子树 右子树 树根