树和堆(julyedu网课整理)
1 定义
1.1 树的定义
它是由n(n>=1)个有限节点组成一个具有层次关系的集合。把它叫做“树”是因为它看起来像一棵倒挂的树,也就是说它是根朝上,而叶朝下的。它具有以下的特点:
- 每个节点有零个或多个子节点
 - 没有父节点的节点称为根节点
 - 每一个非根节点有且只有一个父节点
 - 除了根节点外,每个子节点可以分为多个不相交的子树
 
1.2 堆的定义
堆的实现通过构造二叉堆(binary heap),实为二叉树的一种;由于其应用的普遍性,当不加限定时,均指该数据结构的这种实现。这种数据结构具有以下性质:
- 任意节点小于(或大于)它的所有后裔,最小元(或最大元)在堆的根上(堆序性)。
 - 堆总是一棵完全树。即除了最底层,其他层的节点都被元素填满,且最底层尽可能地从左到右填入。
 - 将根节点最大的堆叫做最大堆或大根堆,根节点最小的堆叫做最小堆或小根堆。
 
2 基本操作
2.1 树的基本操作
- 遍历:前中后序遍历;层次遍历
 - 序列化与反序列化
 - 深度:最大深度,最小深度。
 
2.2 堆的基本操作
- 插入元素,调整新元素使之满足堆条件。
 - 删除元素,调整新元素使之满足堆条件。
 
3 树和堆的应用场景
- C++ STL的set与map(红黑树)
 - 数据库索引(B+树)
 - 优先队列(堆)
 - 语法树
 - 决策树
 - 游戏场景管理(八叉树或BSP树)
 
4 树和堆相关算法
- 递归
 - 分治
 - 深度优先搜索
 - 广度优先搜索
 
5 例题
求公共最近的父节点:给定一棵二叉树,找到两个节点的最近公共父节点(LCA)。最近公共祖先是两个节点的公共的祖先节点且具有最大深度。

对于上面例子:LCA(3, 5) = 4; LCA(6, 7) = 7
5.1 思路
- 如果以LCA为根节点,那么A、B必定分别位于该节点的左右子树。
 - 如果不满足条件1,A、B都位于LCA的左子树,那么显然LCA左子树上的节点应该成为LCA。
 
==> ∴ 从根节点开始,对于根节点的左右子树结点都进行如下循环:找左子树,如果存在A或B返回left(值等于结点值);找右子树,如果存在A或B返回right(值等于结点值)。如果对于某一个结点,left和right都是有值的,那么就返回这个结点。
5.2 Demo
TreeNode lowestCommonAncestor(TreeNode root, TreeNode A, TreeNode B) {
    // write your code here
    if(root ==  null || root == A || root == B){
		return root;
	}
	TreeNode left = lowestCommonAncestor(root.left, A, B);
	TreeNode right = lowestCommonAncestor(root.right, A, B);
	if(left && right){
		return root;		
	}else{
		left ? return left : return right;
	}
}