1.什么是树?
树(Tree)是n(n>=0)个结点的有限级,n=0时称为空树,在任意一颗非空树中:
- 有且仅有一个特定的结点称为根(root);
- 当n>1时,其余结点可分为m(m>0)个互不交互的有限集T1,T2,…,Tm,其中每一个集合本身又是一颗树,并且称为根的子树(SubTree)
2.树的构成
2.1 节点
- 分类
节点分类 | 特点 | 说明 |
---|---|---|
根(root) | 没有父节点只有子节点的节点 | |
叶子(leaf)/终端节点 | 没有子节点或者子节点是空的节点 | 叶子结点度为0 |
分支节点/非终端节点 | 分支节点包含根节点 |
- 关系
- 双亲节点或父节点(Parent):若一个节点含有子节点,则这个节点称为其子节点的父节点。
- 孩子节点或子节点(Child):一个节点含有的子树的根节点称为该节点的子节点。
- 兄弟节点(Sibling):具有相同父节点的节点互称为兄弟节点
- 节点的祖先:从根到该节点所经分支上的所有节点;
- 节点的子孙:以某节点为根的子树中任一节点都称为该节点的子孙。
2.2 度
- 节点的度数:节点孩子的个数
- 树度:书中节点的度的最大值
2.3 层次
- 层次:从根开始定义起,根为第1层,根的子节点为第2层,以此类推
2.4 深度与高度
维基百科
- 节点的高度:节点到最远叶子节点的最长路径上边的数量。叶子节点高度为0。
- 节点的深度:节点到根节点的路径上边的数量。所有根节点深度为0。
- 树的高度:树的高度等于根节点的高度,等于最远叶子节点的深度。
- 树的深度:树的深度等于树的高度。
- 树的宽度:两个最长路径的叶子节点之间节点数。
Leetcode- 树的深度:根节点到最远叶子节点之间最长路径上**
节点
**的数量。- 树的高度:根节点和最远叶子节点之间最长路径上**
边
**的数量。
树的深度与树的高度是树中节点的最大层次
练习
/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode(int x) : val(x), left(NULL), right(NULL) {}
* };
*/
class Solution {
public:
int minDepth(TreeNode* root) {
// 此题需注意叶子节点的定义,比较抽象,可以想象一下输入为[1,2]的情况,
// 此时如果单纯返回 1 + min(minDepth(root->left), minDepth(root->right)),则得 1,因为结点1的右子节点深度计算出来为 0,
// 而实际上,节点2才是符合要求的节点。所以不能单纯的递归比较2个子节点谁的深度小。
// 首先,节点为空,直接返回0
if(root == nullptr) return 0;
// 其次,若当前节点的左右子节点均存在,说明***当前节点不是叶子节点,其孩子节点的性质也无法判定***,故返回较小的孩子节点深度
if(root->left && root->right) return 1 + min(minDepth(root->left), minDepth(root->right));
// 最后,若当前节点的左右子节点有一个不存在,则说明***当前节点的子节点中存在叶子节点***,故返回不为空的孩子节点(叶子节点)的深度
// 当然了,若当前节点的左右子节点都不存在,那它就是叶子节点,总深度直接 +1 就好了,也符合这个 return 句法。
return 1 + max(minDepth(root->left), minDepth(root->right));
}
/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode() : val(0), left(nullptr), right(nullptr) {}
* TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
* TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}
* };
*/
class Solution {
public:
int maxDepth(TreeNode* root) {
if(nullptr==root)return 0;
if(root->left==nullptr||root->right==nullptr){
return max(maxDepth(root->left),maxDepth(root->right))+1;
}
return max(maxDepth(root->left),maxDepth(root->right))+1;
}
};
class Solution {
public:
int maxDepth(Node* root) {
int maxi = 0;
if(!root) return 0;
//找出所有子树中最高的那个的长度
for(Node* it:root->children){
if(it) maxi = max(maxi,maxDepth(it));
}
//树的长度等于最高的子树的长度+1
return maxi+1;
}
};
3. 树的分类
树按照子节点的数量分为二叉树和多叉树。
- 二叉树是n(n>=0)个结点的有限集合,该集合或者为空集(称为空二叉树),每个节点最多有2个子节点,分别称为根结点的左子树和右子树。
- 多叉树是n(n>=0)个结点的有限集合,该集合或者为空集(称为空树)。每个节点有多个子节点。
分类 | 经典分类 |
---|---|
二叉树 | 平衡二叉树、二叉搜索树、AVL、堆、红黑树 |
多叉树 | 2-3树、B树、B+树 |
树按照子树是否有序分为有序树和无序树。 |
- 有序树:节点各子树从左到右有次序(不能互换)。
- 无序树:节点各子树从左到右无次序(能互换)。
二叉树是最简单,最基础的树结构。
特殊的树
- 满二叉树(Full Binary Tree):二叉树中的每个结点恰好有两个孩子结点且所有叶子结点都在同一层。
- 完全二叉树(Complete Binary Tree): 每层结点都完全填满,在最后一层上如果不是满的,则只缺少右边的若干结点。
- 深度为k,有n个结点的二叉树,当且仅当其每一个结点都与深度为k的满二叉树中编号从1到n的结点一一对应,该二叉树称为完全二叉树。2^{k-1} ≦n≦2^k-1
不同的书籍对满二叉树和完全二叉树定义不一样。
《算法导论》第3版
- 满二叉树:每个节点是叶节点或者度为2.
- 完全二叉树:所有叶节点深度相同,且所有内部节点度为2. (树的节点总数达到最大)