是否是满二叉树。
满二叉树:除最后一层无任何子节点外,每一层上的所有结点都有两个子结点的二叉树。
一个二叉树,如果每一个层的结点数都达到最大值,则这个二叉树就是满二叉树。并且,一个满二叉树的第K层,结点总数是(2^k) -1。
从数学上看,满二叉树的各个层的结点数形成一个首项为1,公比为2的等比数列。
1
、
2
、
4
、
8
、
16...
.
.
.
{1、2、4、8、16 ...\ ... }
1、2、4、8、16... ...,每一层的结点数为上上一层的2倍,并且
{
前
n
−
1
层
的
结
点
数
}
=
{
第
n
层
的
结
点
数
−
1
}
\{前 n-1 层的结点数\} = \{第 n 层的结点数 - 1\}
{前n−1层的结点数}={第n层的结点数−1}
使用层序遍历判断每层是否达到最大值。
bool IS_FULL_BinTree(struct BtNode* ptr)
{
bool res = true;
if (ptr == NULL) return res; // 空树也是满二叉树
std::queue<struct BtNode*> que;
que.push(ptr);
int floor = 1; // 层
while (!que.empty())
{
int i = 0; // 记录该层元素的个数
while (!que.empty() && i < floor)
{
ptr = que.front(); que.pop();
if (ptr->leftchild != NULL)
{
que.push(ptr->leftchild);
}
if (ptr->rightchild != NULL)
{
que.push(ptr->rightchild);
}
++i;
}
if (i < floor) // 该层元素不够,树不满
{
res = false;
break;
}
floor *= 2;
}
return res;
}
使用递归方法判断相当方便,只是执行效率要差得多。思路:左右子树皆为满二叉树且深度相同。
bool Is_Full_BinTee(struct BtNode* ptr)
{
return (ptr == NULL) || (Is_Full_BinTee(ptr->leftchild) && Is_Full_BinTee(ptr->rightchild)
&& GetDepth(ptr->leftchild) == GetDepth(ptr->rightchild));
}
是否是完全二叉树。
完全二叉树可以理解为满二叉树的一种特殊情况,可视为最后一层的结点从右至左连续缺省若干个结点。比如下面这棵树。
左边为一颗满二叉树,从它的最后一层缺省掉结点G、F之后就是一颗完全二叉树。并且一个满二叉树也是一个完全二叉树。
思路分析:观察下图中所有叶子结点。
如果我们在遍历时,把二叉树中指向NULL的结点也遍历的话,图左的满二叉树按照层序遍历输出 : { A , B , E ⏟ 2 , C , D , F , G ⏟ 4 , N U L L , N U L L , N U L L , N U L L , N U L L , N U L L , N U L L , N U L L ⏟ 8 } {A,\ \ \ \underbrace{B,E}_{2},\ \ \ \underbrace{C,D,F,G}_{4},\ \ \ \underbrace{NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL}_{8}} {A, 2 B,E, 4 C,D,F,G, 8 NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL}
图左的满二叉树按照层序遍历输出:
{
A
,
B
,
E
⏟
2
,
C
,
D
,
N
U
L
L
,
N
U
L
L
⏟
4
,
N
U
L
L
,
N
U
L
L
,
N
U
L
L
,
N
U
L
L
⏟
4
}
{A,\ \ \ \underbrace{B,E}_{2},\ \ \ \underbrace{C,D,NULL,NULL}_{4},\ \ \ \underbrace{NULL,NULL,NULL,NULL}_{4}}
{A, 2
B,E, 4
C,D,NULL,NULL, 4
NULL,NULL,NULL,NULL}
我们可以发现,完全二叉树在层次遍历时,最后输出的内容为一连串不间断的 NULL。
而如果是非完全二叉树就会出现如 { A , B , . . . . . . n u l l , . . . . . . n u l l ⏟ n ∗ n u l l , N , n u l l , . . . . . . n u l l ⏟ m ∗ n u l l ⏞ } {{A,B,...\ ...\ \overbrace{\underbrace{null,... \ ... null}_{n*null},N, \underbrace{null,...\ ... null}_{m*null}}}} {A,B,... ... n∗null null,... ...null,N,m∗null null,... ...null } 的情况。因为完全二叉树是由满二叉树从左至右连续缺省得到,因此,在最后的n个null结点中是不会突然出现有效结点的,如公式中的 N 结点。
使用层序遍历,检查队列中最后的元素是否为一串连续的NULL结点。
bool IS_Comp_BinTree(struct BtNode* ptr)
{
bool res = true;
if (ptr == NULL) return res;
std::queue<struct BtNode*> que;
que.push(ptr);
while (!que.empty())
{
ptr = que.front(); que.pop();
if (ptr == NULL) // null开始
{
while (!que.empty())
{
ptr = que.front(); que.pop();
if (ptr != NULL) // 检查是否全为null
{
res = false;
break;
}
}
}else
{
que.push(ptr->leftchild);
que.push(ptr->rightchild);
}
}
return res;
}
是否是二叉搜索树
一个二叉搜索树具有如下特征:
- 节点的左子树只包含小于当前节点的数。
- 节点的右子树只包含大于当前节点的数。
- 所有左子树和右子树自身必须也是二叉搜索树。
力扣leetcode:98.验证二叉搜索树
力扣官方题解:验证二叉搜索树
中序遍历
对于二叉搜索树,中序遍历时所得到的结点是升序的。因此我们只需验证这一点就好了。
class Solution {
public:
bool InOrder(TreeNode* root, long& pre) {
if (root == NULL) {
return true;
}
if (!InOrder(root->left, pre)) { // 中序遍历,递归寻找左孩子
return false;
}
if (root->val <= pre) { // pre记录的是前一个结点的值
return false;
}
pre = root->val; // 更新pre的值
return InOrder(root->right, pre); // 遍历右子树
}
bool isValidBST(TreeNode* root) {
long pre = LONG_MIN;
return InOrder(root, pre);
}
};
作者:huwt
链接:https://leetcode-cn.com/problems/validate-binary-search-tree/solution/98-yan-zheng-er-cha-sou-suo-shu-zhong-xu-bian-li-w/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
值得注意的是,中序遍历BST树的结果是一个升序的序列,因此,我们使用pre记录前一个结点的值,只需要判断当前值是否大于pre即可。
维护最大最小值
借助辅助函数helper(),进行递归。采用分而治之的策略分别验证左子树 or 右子树是否为BST数。
class Solution {
public:
bool helper(TreeNode* root, long min, long max) {
if (root == NULL) { // 空树也是BST树
return true;
} // 如果是左子树,当前结点需要小于父节点,即 root->val < max,右子树则大于 root->val > min
if (root->val <= min || root->val >= max) {
return false;
} // 分治
return helper(root->left, min, root->val) && helper(root->right, root->val, max);
}
bool isValidBST(TreeNode* root) {
long min = LONG_MIN;
long max = LONG_MAX;
return helper(root, min, max);
}
};
作者:huwt
链接:https://leetcode-cn.com/problems/validate-binary-search-tree/solution/98-yan-zheng-er-cha-sou-suo-shu-zhong-xu-bian-li-w/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
以上引用自力扣的 98.验证二叉搜索树 题解。
后面先留着,以后更新 ... ...
是否是平衡二叉树
。
是否是对称二叉树
。
是否是一棵树的子树
。
两个二叉树是否相同
。