概念与术语
节点的度:节点的后继数
树的度:最大的节点的度
叶子节点:度为零的节点
根节点:没有父节点的那个节点
深度(高度):层数,假设根节点为第一层。
森林:两棵以上的树构成森林。
分类
无序树:自由树
有序树
有序树
二叉树
每个节点都至多有两个后继(度<=2)
完全二叉树
若树的深度是k,那么除了第k层之外的所有层,节点数都达到最大,且第k层的节点从左到右依次紧密地排列。
满二叉树
叶子节点都在第k层的完全二叉树。
二叉排序树
由于折半查找只能应用于已排序的顺序表的搜索,如果想要加快链表的搜索速度该怎么办呢?将链表插入成二叉排序树,再搜索这个树。如果树是平衡的,时间复杂度可以达到O(logn),与折半查找相同。
平衡二叉树
如果被插入的链表是已排序的,那么若还按照二叉排序树的规则,将链表改装成树,那么生成的树会非常高,退化为一个链表,此时的搜索复杂度又退化为O(n)。所以需要将树改装成平衡的再搜索。
二叉树的性质
1.若根节点是第一层,那么第i层的节点数最多为2i-1。
2.若共有k层,则树最多有2k -1个节点。
3.若叶子节点树为N0 (度为0),度为2的节点数为N2,那么N0=N2+1
4.具有N个节点的满二叉树深度为log2(N+1)
二叉树的遍历
深度优先遍历
沿着树的深度进行遍历,有先序、中序、后序三种遍历方式。使用递归实现。
广度优先遍历
层次遍历。从上到下从左到右。使用队列来实现。
实现
# 树
# 初始化和插入
# 节点插入操作借助了层次遍历的思想,使用队列来实现
# 二叉树的节点
class Node:
def __init__(self, x, left=None, right=None):
self.item = x
self.left = left
self.right = right
# 以完全二叉树的方式遍历和插入节点。
class Tree:
def __init__(self, node=None):
self.root = node
def add(self, x):
node = Node(x)
if not self.root:
self.root = node
else:
# queue是一个元素外置的顺序表
# 队列头入后出,因为弹出频繁。
queue = [self.root]
while queue:
head = queue.pop(0)
if head.left is None:
head.left = node
return
elif head.right is None:
head.right = node
return
else:
queue.append(head.left)
queue.append(head.right)
def breadth_travel(self):
"""层次遍历"""
if not self.root:
return
else:
queue = []
queue.append(self.root)
while queue:
head = queue.pop(0)
print(head.item,end=' ')
if head.left:
queue.append(head.left)
if head.right:
queue.append(head.right)
def preorder(self):
"""先序遍历"""
return self.__preorder(self.root)
#递归必然有迭代参数,需要外层把私有变量传进去。
def __preorder(self,root):
if not root:
return
print(root.item,end=' ')
self.__preorder(root.left)
self.__preorder(root.right)
def inorder(self):
"""中序遍历"""
return self.__inorder(self.root)
def __inorder(self,root):
if not root:
return
self.__inorder(root.left)
print(root.item,end=' ')
self.__inorder(root.right)
def postorder(self):
"""后序遍历"""
return self.__postorder(self.root)
def __postorder(self,root):
if not root:
return
self.__postorder(root.left)
self.__postorder(root.right)
print(root.item,end=' ')
if __name__ == '__main__':
tree = Tree()
for i in range(5):
tree.add(i)
tree.breadth_travel()
print()
tree.preorder()
print()
tree.inorder()
print()
tree.postorder()
print()