题1:
指路:LeetCode235 二叉搜索树的最近公共祖先
思路与代码:
题目点明了是二叉搜索树,那么特性就是有序。非空左子树的值一定小于非空右子树的值;非空右子树的值一定大于根节点值;左右都是二叉搜索树。而公共祖先是介于两节点之间的节点。结合二叉搜索树的特性,我们可以知道:从上往下遍历如果遍历到的节点值在两个节点值的中间那么这个节点就是这两个节点的最近公共祖先而非次近。对于左右子树的遍历方向:如果当前节点值在两节点值的左边(当前节点值小于两节点值)那么我们就要去右子树找;相同的,如果当前节点值在两节点值的右边(当前节点值大于两节点值)那么我们就要去左子树找。当然,也可以往下看看,如果再往下找也许会丢失左节点,也许会丢失右节点(画个图就很清晰了)。代码如下:
class Solution {
private:
TreeNode* traversal(TreeNode* cur, TreeNode* p, TreeNode* q) {
if (cur == NULL) return cur;
TreeNode* left;
TreeNode* right;
if (cur->val > p->val && cur->val > q->val) {
left = traversal(cur->left, p, q);
if (left != NULL)
return left;
}
if (cur->val < p->val && cur->val < q->val) {
right = traversal(cur->right, p, q);
if (right != NULL)
return right;
}
return cur;
}
public:
TreeNode* lowestCommonAncestor(TreeNode* root, TreeNode* p, TreeNode* q) {
return traversal(root, p, q);
}
};
题2:
指路:LeetCode701 二叉搜索树中的插入操作
思路与代码:
结合二叉搜索树的特性我们得出在叶节点下插入新节点。如果叶节点的值小于给定的值,则把给定值的节点插入在叶节点的右子树,反之则插入在左子树。递归节点到叶节点后定义一个新节点,完成单层递归后往上回到节点相应的子树。代码如下:
class Solution {
public:
TreeNode* insertIntoBST(TreeNode* root, int val) {
if (root == NULL) { //叶节点
TreeNode* node = new TreeNode(val);
return node;
}
if (root->val > val) {
root->left = insertIntoBST(root->left, val) ;
}
if (root->val < val) {
root->right = insertIntoBST(root->right, val) ;
}
return root;
}
};
题3:
指路:LeetCode 450 删除二叉树中的节点
思路与代码:
对于删除节点我们分为三种情况。第一种没在树中找到要删除的节点;第二种为删除叶节点;第三种为删除树中节点。第三种情况又分为三种情况:左节点不为空右节点为空;左节点为空右节点不为空;左节点不为空右节点不为空。但我现在肩伤犯了,先写到这里。代码如下:
class Solution {
public:
TreeNode* deleteNode(TreeNode* root, int key) {
if (root == NULL) return root;
if (root->val == key) {
if (root->left == NULL && root->right == NULL) { // 第一种情况
delete root;
return NULL; // 删除的是叶节点
}
else if (root->left != NULL && root->right == NULL) { // 第二种情况
auto retNode = root->left;
delete root;
return retNode; // 左节点为空右节点不为空
}
else if (root->left == NULL && root->right != NULL) { // 第三章情况
auto retNode = root->right;
delete root;
return retNode; // 左节点不为空右节点为空
}
else {
TreeNode* cur = root->right; // 用右节点做删除后的顶替者
while (cur->left != NULL)
cur = cur->left;
cur->left = root->left;
TreeNode* tmp = root;
root = root->right;
delete tmp;
return root;
}
}
// 单层循环逻辑:
if (key < root->val) root->left = deleteNode(root->left, key);
if (key > root->val) root->right = deleteNode(root->right, key);
return root;
}
};