235. 二叉搜索树的最近公共祖先
思路:如果p的值大于当前节点的值,q的值小于当前结点的值,那么当前节点就是最近公共祖先。因为当前节点的左子树没有q,当前节点的右子树没有p;
因此,只需要判断p,q的值同时大于或者同时小于当前节点,进行遍历。
class Solution {
public:
TreeNode* lowestCommonAncestor(TreeNode* root, TreeNode* p, TreeNode* q) {
if(root == NULL)return NULL;
//p,q的值都小于当前节点的值,那么遍历左子树
if(root->val > p->val && root->val > q->val){
TreeNode* left = lowestCommonAncestor(root->left, p, q);
if(left)return left;
}
//p,q的值都小于当前节点的值,那么遍历右子树
if(root->val < q->val && root->val < p->val){
TreeNode*right = lowestCommonAncestor(root->right, p, q);
if(right)return right;
}
return root;
}
};
迭代法
class Solution {
public:
TreeNode* lowestCommonAncestor(TreeNode* root, TreeNode* p, TreeNode* q) {
if(root == NULL)return NULL;
while(root != NULL){
if(p->val < root->val && q->val < root->val){
root = root->left;
}
else if(p->val > root->val && q->val > root->val){
root = root->right;
}
else return root;
}
return NULL;
}
};
701.二叉搜索树中的插入操作
递归法
root->left 和 root->right 是连接要插入的节点node与二叉树的,node的返回由root->left 或root ->right接收。
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;
}
};
迭代法
class Solution {
public:
TreeNode* insertIntoBST(TreeNode* root, int val) {
if(root == NULL){
TreeNode* node = new TreeNode(val);
return node;
}
TreeNode* parent = root; //记录父结点;
TreeNode* cur = root; //记录当前节点
//找到要插入节点的父结点
while(cur){
parent = cur; //很重要,是作为父结点的,一旦cur为空,就进不了循环了,此时插入节点的父结点就是parent
if(cur->val > val)cur = cur->left;
else cur = cur->right;
}
TreeNode* node = new TreeNode(val);
//判断该节点插入左子树还是右子树
if(parent->val > val){
parent->left = node;
}else{
parent->right = node;
}
return root;
}
};
450.删除二叉搜索树中的节点
分五种情况进行判断,在进行终止条件的判定中,就将五种判断逻辑分别写上。
后面再遍历过程中,要用左孩子或者右孩子接住返回值,这是将返回值进行安放。
class Solution {
public:
TreeNode* deleteNode(TreeNode* root, int key) {
//要删除的节点为空
if(root == NULL)return NULL;
//要删除的节点不为空
if(root->val == key){
//1.要删除的节点是叶子结点,左右子树都为空,令返回值为NULL,即上一层会接一个NULL
if(root->left == NULL && root->right == NULL){
delete root;
return NULL;
}
//2.要删除的节点左子树不为空,右子树为空,返回该节点的左子树
else if(root->left != NULL && root->right == NULL){
auto retNode = root->left;
delete root;
return retNode;
}
//3.要删除节点的左子树为空,右子树不为空,返回该节点的右子树
else if(root->left == NULL && root->right != NULL){
auto retNode = root->right;
delete root;
return retNode;
}
//4.要删除节点的左右子树都不为空,将右子树保留,左子树接在右子树的左子树上
else {
TreeNode* cur = root->right;
while(cur->left){
cur = cur->left; //找到左子树的叶子节点
}
cur->left = root->left;
TreeNode* temp = root; //保存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;
}
};