深度:
- 从根到节点路径的长度
- 树的每一层包含了同一深度的所有节点
高度:
- 根到叶节点最长的路径
- 树中节点的最大深度
二叉搜索树的所有操作的时间复杂度为O(h),即O(lgn)(在排序中已证明)。
二叉搜索树的操作复杂度和高度密切相关。为了防止子树之间的高度相差过大,使用随机次序插入元素时的高度为O(lgn)
由于无法保证总是随机的构造二叉搜索树,所以通过红黑树和B树(磁盘的数据库维护)
红黑树:平衡二叉树的一种。通过节点的颜色保证路径之间的长度相差不超过一倍。STL的map和set是用红黑树实现的。所有操作的复杂程度为O(lgn)
- 根结点和叶节点为黑色
- 父节点为红色,子节点都为黑色
- 每条路径的黑色节点数目一致
所以新增节点的颜色为红色( 根据第3条),父节点的颜色为黑色(根据第4条)。然后新节点按照二叉搜索树的规则插入。发现不符合规则时需要进行旋转和调整。
根据第2条,每条路径有1半以上的节点为黑色。n≧2^h/2-1.所以h≤2lg(n+1)
Leetcode100
比较2个树是否相同
bool isSameTree(TreeNode* p, TreeNode* q) {
//经典结构
if (p == NULL || q == NULL)
return (p == q);
return (p->val == q->val && isSameTree(p->left, q->left) && isSameTree(p->right, q->right));
}
调用isSameTree函数之前必须确定q和p不为空,否则会抛出member access within null pointer of type ‘struct ListNode’
Leetcode112
判断路径上的节点之和是否为给定值
- 注意树为空的情况和叶节点的判断
- 判断到叶节点是root->val == sum而不是sum==0
bool hasPathSum(TreeNode *root, int sum) {
if (root == NULL) return false;
if (root->val == sum && root->left == NULL && root->right == NULL) return true;
return hasPathSum(root->left, sum-root->val) || hasPathSum(root->right, sum-root->val);
}
Leetcode98
判断1棵树是否为二叉搜索树(出现等于也说明不是)
使用中序遍历读取序列是从小到大