相关术语
树可以被看做图的一种特例, 即"有向无环图"
二叉树中每个元素都称为节点。
根节点 (root node)
父节点(parent node)
n个子节点(child node)
节点的度 (degree)
节点所拥有的子树的数目称为该节点的度
叶节点(leaf node)
边 (edge node)
路径 (path)
子树(subtree)
层数(level)
最常见的树--二叉树
最多有两个子节点的树(binary tree)
“二叉树中的度“是指树中最大的结点度,叶子结点是终端结点,是度为 0 的结点。
二叉树的度是指树中所以结点的度数的最大值。二叉树的度小于等于2,因为二叉树的定义要求二叉树中任意结点的度数(结点的分支数)小于等于2 ,并且两个子树有左右之分,顺序不可颠倒。
叶子结点就是度为0的结点,也就是没有子结点的结点叶子。如n0表示度为0的结点数,n1表示度为1的结点,n2表示度为2的结点数。在二叉树中:n0=n2+1;N=n0+n1+n2(N是总结点)。
满二叉树 (full binary tree):
除最后一层无任何子节点外,每一层上的所有结点都有两个子结点的二叉树。
完全二叉树(Complete Binary Tree)
若设二叉树的深度为h,除第 h 层外,其它各层 (1~h-1) 的结点数都达到最大个数,第 h 层所有的结点都连续集中在最左边,这就是完全二叉树。
图1: 完全二叉树
二叉搜索树
定义 (binary search tree)
- 递归性质
- 周游性质: 中序周游的结果是个由小到大的有序排列
深度优先周游
前序周游
中序周游
后序周游
递归是实现周游的最好方式
广度优先周游
二叉搜索树的基本操作
搜索
找中序周游后序
插入
删除
- 删除节点是叶节点
- 删除节点有一个子节点
- 删除节点有两个子节点
高级树结构
平衡二叉树 (balanced tree)
字典树 (Trie)
B树
树的实现方式
链表实现
顺序存储
----只适用于完全二叉树
利用下标计算父子关系
- 对于任何一个二叉树节点, 如果它存储在数组的第i个位置: 父节点为( i - 1)/2, 向上取整
- 左右子节点分别对应2*i+1和2*i+2
基于搜索的应用
type ahead (字典树)
ordered map (平衡二叉树)
文件系统索引(B树)
判断树的性质
分而治之(递归)
以周游为主
题目:
平衡二叉树 Leetcode_110
这题先看了一眼答案,实际上思路是很好理解的,我们要实现两个递归
1. 递归去判断每个(子)树的深度, 注意,不管数是否平衡,它的高度都是由最深的子树的深度决定的
所以,递归的逻辑是: 父节点的深度 = max(左,右子树的深度)+1
递归的终点是,针对空树, 深度为0
求树的深度的递归实现:
int getHeight(TreeNode* node)
{
if (!node)
{
return 0;
}
return (max(getHeight(node->left),getHeight(node->right))+1);
}
2. 递归去判断子树是否为平衡二叉树
判断一棵树是否为平衡二叉树需要满足,
1. 左右子树的深度差小于等于1
2. 左右子树需要是平衡二叉树
终止条件, 对于空树,判断它为平衡二叉树= true
判断树是否为平衡二叉树的递归实现:
bool isBalanced(TreeNode* root) {
if (!root)
return true;
return (abs(getHeight(root->right)-abs(getHeight(root->left)))<=1\
&&isBalanced(root->left)&&isBalanced(root->right));
}