树:
根结点:非空树中没有前驱结点的结点
结点的度:结点拥有子树的个数
数的度:树内各结点度的最大值
度为零的结点:终端结点,叶子
度不为零的结点:非终端结点,分支结点
根以外的分支结点称为内部结点
结点的子树的根称为该子树的孩子,该结点是孩子的双亲
有共同双亲的结点称为兄弟
从根到该结点经过的所有结点称为祖先
深度/高度:树的最大层次
有序树:如果树中从左到右是有序的
首先搜索二叉树和完全二叉树的含义是:
搜索二叉树:搜索二叉树是一种特殊有序的二叉树,如果一棵树不为空,并且如果它的根节点左子树不为空,那么它左子树上面的所有节点的值都小于它的根节点的值,如果它的右子树不为空,那么它右子树任意节点的值都大于他的根节点的值,它的左右子树也是二叉搜索树。(参考:(8条消息) 搜索二叉树_angry_youth的博客-CSDN博客_搜索二叉树)
完全二叉树:除了最后一层以外,均被完全填充,并且所有结点均向左对齐
参考:(8条消息) 完美二叉树, 完全二叉树和完满二叉树_积累点滴,保持自我-CSDN博客_完全二叉树
思路:搜索二叉树按照中序遍历应该得到的是一个升序的结果
根据讲解,判断完全二叉树用层次遍历
例题解法:
class Solution {
public:
/**
*
* @param root TreeNode类 the root
* @return bool布尔型vector
*/
vector<bool> judgeIt(TreeNode* root) {4
//创建一个向量,默认值为false
vector<bool> res(2, false);
//假如为空树的时候,该树既为完全二叉树,也是搜索二叉树
if (!root) {
res[0] = true;
res[1] = true;
return res;
}
//创建int型的向量存储通过中序遍历得到的数组
vector<int> inorderRes;
inorder(root, inorderRes); // 中序遍历
res[0] = true;
// 判断中序遍历结果是否升序
for (int i = 0; i < inorderRes.size() - 1; i ++) {
if (inorderRes[i] >= inorderRes[i + 1]) {
res[0] = false;
break;
}
}
// 层次遍历
res[1] = levelOrder(root);
return res;
}
void inorder(TreeNode* root, vector<int>& inorderRes) {
if (!root) return;
inorder(root->left, inorderRes); // 访问左子树
inorderRes.push_back(root->val); // 访问根结点
inorder(root->right, inorderRes); // 访问右子树
return;
}
bool levelOrder(TreeNode* root) {
//创建队列q,是一个树节点
queue<TreeNode*> q;
q.push(root); //放入第一层结点
//假如队列中第一个元素不为空,以第一个元素为树的根,将根pop出,然后再将左右的值push进
//假设此根节点中有左右子树,则会将左右子树push进去,此时队列内有值,pop一个,如果没有,则是完全二叉树,如果还有,则不是完全二叉树
while (q.front()) {
TreeNode* tmp = q.front();
q.pop();
q.push(tmp->left);
q.push(tmp->right);
}
// 队列元素必须全为空
while (q.size() && !q.front()) {
q.pop();
}
return q.empty();
}
};