树的术语:
1.节点的度(一个节点子节点的个数)
2.树的度(最大的节点的度)
3.父节点
4.子节点
5.兄弟节点
6.节点的层次(根为第一层,根的子节点是第二层,计数从1开始)
7.树的高度和深度(最大层次)
8.堂兄弟节点(父节点在同一层的节点的子节点)
9.节点的祖先(从跟到该节点所分支上的所有节点)
10.子孙
11.森林(互不相交的树)
无序树\有序树
有序树有二叉树,哈弗曼树,B树
完全二叉树:除了倒数等二层,其他层的每个节点都有俩子节点
满二叉树:每层都2子节点(最后一层没子节点)
平衡二叉树:当且仅当任何节点的子树的高度差不大于1的二叉树(每一层的节点都有子节点)
二叉排序树(左边的子节点一定比节点的值小,右边的子节点比节点的值大)
树的存储
二叉树的顺序存储:用顺序表,数组,每一层都从左到右,但是这样不方便,读取时不一定能还原原本的结构
链式存储
应用场景:
1.html
2.路由协议
3.mysql数据库索引
4.文件系统的目录结构
5.决策树,其他机器学习算法
一些性质:
对于任意一棵二叉树,叶子节点数为N0,度为2的节点总数为N2,则N0=N2+1
#建立树
class Node(object):
def __init__(self, item):
self.elem = item
self.lchild = None
self.rchild = None
class Tree(object):
def __init__(self):
self.root = None
def add(self, item):
# 需要一个队列,每次在队尾放入新访问的元素,每次在对头判断当前节点有没有满
node = Node(item)
if self.root is None:
self.root = node
return
queue= [self.root]
while queue: # bool([None])是True
cur_node = queue.pop(0)
if cur_node.lchild is None:
cur_node.lchild = node
return
else:
queue.append(cur_node.lchild)
if cur_node.rchild is None:
cur_node.rchild = node
return
else:
queue.append(cur_node.rchild)
def breadth_travel(self):
# 广度遍历
if self.root is None:
return
queue = [self.root]
while queue:
cur_node = queue.pop(0)
print(cur_node.elem, end=" ")
if cur_node.lchild is not None:
queue.append(cur_node.lchild)
if cur_node.rchild is not None:
queue.append(cur_node.rchild)
# 深度遍历(三种方式)
# 前:根左右,中:左根右,后:左右根
# 每次都需要划分子树
def preorder(self, node):
# 前序
# 写代码时先写出遍历的时候做的事情:
# print(node.elem)
# preorder(node.lchild)
# preorder(node.rchild)
if node is None:
return
print(node.elem, end=" ")
self.preorder(node.lchild)
self.preorder(node.rchild)
def inorder(self, node):
# 中序
if node is None:
return
self.inorder(node.lchild)
print(node.elem, end=" ")
self.inorder(node.rchild)
def postorder(self, node):
# 中序
if node is None:
return
self.postorder(node.lchild)
self.postorder(node.rchild)
print(node.elem, end=" ")
if __name__ == "__main__":
tree = Tree()
tree.add(1)
tree.add(2)
tree.add(3)
tree.add(4)
tree.add(5)
tree.add(6)
tree.add(7)
tree.add(8)
tree.add(9)
#print(bool([None]))
tree.breadth_travel()
print(" ")
tree.preorder(tree.root)
print(" ")
如何通过前,中或者中,后序重建二叉树:
https://leetcode-cn.com/problems/zhong-jian-er-cha-shu-lcof/
思路:
对树进行划分,要用递归去做(因为二叉树本身就是递归定义的。)
后序遍历应用:
表达式求值(左右子节点上存值,根节点上存运算符)
中序遍历应用:
生成全括号中缀表达式
中缀表达式是一个通用的算术或逻辑公式表示方法, 操作符是以中缀形式处于操作数的中间(例:3 + 4),中缀表达式是人们常用的算术表示方法。
二叉堆逻辑结构上像二叉树,却是用非嵌套的列表来实现的
最小key(优先度最高的)拍在队首的称为“最小堆min heap”
反之“最大堆max heap”