235. 二叉搜索树的最近公共祖先
题目链接:235. 二叉搜索树的最近公共祖先
此题比上一题二叉树的的最近公共祖先容易一些,可以利用二叉搜索树的性质,当p和q在根节点左侧,遍历左子树,都在右侧遍历右子树,在两侧则根节点就是最近公共祖先。
迭代法
class Solution {
public:
TreeNode* lowestCommonAncestor(TreeNode* root, TreeNode* p, TreeNode* q) {
if (root == NULL) return root;
if (p->val < root->val && q->val < root->val) {
return lowestCommonAncestor(root->left, p, q);
}
if (p->val > root->val && q->val > root->val) {
return lowestCommonAncestor(root->right, p, q);
}
return root; //在两侧的情况
}
};
迭代法
class Solution {
public:
TreeNode* lowestCommonAncestor(TreeNode* root, TreeNode* p, TreeNode* q) {
while (root) {
if (root->val > p->val && root->val > q->val) { //都在左侧
root = root->left;
} else if (root->val < p->val && root->val < q->val) {//都在右侧
root = root->right;
} else return root; //在两侧
}
return NULL;
}
};
701. 二叉搜索树中的插入操作
题目链接:701. 二叉搜索树中的插入操作
看似很麻烦,但是在二叉搜索树中插入都可以转换为直接在叶子节点插入,所以不需要改动二叉树的结构。
class Solution {
public:
TreeNode* insertIntoBST(TreeNode* root, int val) {
if (root == nullptr) { //此节点就是要插入的位置
TreeNode* node = new TreeNode(val);
return node;
}
if (val < root->val) {
root->left = insertIntoBST(root->left, val);
} else {
root->right = insertIntoBST(root->right, val);
}
return root;
}
};
450. 删除二叉搜索树中的节点
题目链接:450. 删除二叉搜索树中的节点
此题要删除二叉树中的节点,所以大多情况需要改动树的结构
有以下几种情况:
- 树中无要删除的节点,此时直接返回
- 树中有要删除的节点
- 要删除的节点是叶子结点,此时直接返回一个空
- 要删除的节点左不为空,右为空,让他的父节点直接指向左
- 要删除的节点左为空,右不为空,让他的父节点直接指向右
- 要删除的节点左右都不为空,此时最复杂,可以让他的右节点作为此根节点,然后其左子树接在右子树的最左边子树
class Solution {
public:
TreeNode* deleteNode(TreeNode* root, int key) {
if (root == nullptr) return nullptr;
if (root->val == key) {
if (root->left == nullptr && root->right ==nullptr) {
delete root;
return nullptr;
} else if (root->left && !root->right) {
TreeNode* node = root->left;
delete root;
return node;
} else if (!root->left && root->right) {
TreeNode* node = root->right;
delete root;
return node;
} else {
TreeNode* cur = root->right;
while (cur->left) {//让cur不断指向左边,保证最小
cur = cur->left;
}
cur->left = root->left;
TreeNode* temp = root;
root = root->right;
delete temp;
return root;
}
}
//利用搜索树的性质
if (key < root->val) root->left = deleteNode(root->left, key);
if (key > root->val) root->right = deleteNode(root->right, key);
return root;
}
};
注意: c++不要忘记手动释放删除的节点