Day20
二叉搜索树
235. 二叉搜索树的最近公共祖先
理解只要当前节点的值在p和q节点的值的中间,那这个值就是最近的公共祖先,绝对不是次近的,这个题就好做了。
递归法
二叉搜索树本身是有序的,所以不涉及到前中后序的遍历
class Solution {
private:
TreeNode* traversal(TreeNode* cur, TreeNode* p, TreeNode* q){
//先判断当前节点为空的情况
if(cur == NULL) return NULL;
//当前节点的值大于p和q节点的值,则遍历当前节点的左子树
if(cur->val > p->val && cur->val > q->val){
TreeNode* left = traversal(cur->left, p, q);
return left;
}
当前节点的值小于p和q节点的值,则遍历当前节点的右子树
if(cur->val < p->val && cur->val < q->val){
TreeNode* right = traversal(cur->right, p, q);
return right;
}
return cur;
}
public:
TreeNode* lowestCommonAncestor(TreeNode* root, TreeNode* p, TreeNode* q) {
return traversal(root, p, q);
}
};
迭代法
使用while循环进行迭代
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.二叉搜索树中的插入操作
虽然有多种插入方式,导致插入后的结构不是唯一的,但是无论插入什么值,我们都可以在叶子结点找到相应的插入位置
递归法1
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;
}
};
递归法2
迭代法
450.删除二叉搜索树中的节点
难点在于删除之后,要怎样去调整树的结构
添加节点的情况,不用去改二叉搜索树的结构,一定找到一个合适的叶子结点的位置
删除节点的情况,要分五种情况去分析:
①没找到要删的节点
②删除的节点,其左为空,右为空,即叶子结点
③删除的结点,其左不空,右为空,直接让父节点指向其子节点
④删除的结点,其左为空,右不空,直接让父节点指向其子节点
⑤删除的结点,其左不空,右不空,假如我们删除节点7,如下:

我们固定我们的删除方法,即让右孩子当新的父节点,并让左孩子连接到右孩子最左侧节点上
class Solution {
public:
TreeNode* deleteNode(TreeNode* root, int key) {
// 代码整体是一个递归的结构
// ①没找到要删的节点
if(root == nullptr) return root;
if(root -> val == key){
// ②删除的节点,其左为空,右为空,即叶子结点
if(root -> left == nullptr && root -> right == nullptr){
delete root;
return nullptr;
}
// ③删除的结点,其左不空,右为空,直接让父节点指向其子节点
else if(root -> right == nullptr){
TreeNode *retNode = root -> left;
delete root;
return retNode;
}
// ④删除的结点,其左为空,右不空,直接让父节点指向其子节点
else if(root -> left == nullptr){
TreeNode *retNode = root -> right;
delete root;
return retNode;
}
// ⑤删除的结点,其左不空,右不空
else{
// 先找到右孩子最左侧的节点
TreeNode *cur = root -> right;
while(cur -> left != nullptr) cur = cur -> left;
cur -> left = root -> left;
TreeNode* tmp = root;
root = root -> right;
delete tmp;
return root;
}
}
// 进行递归
if(root -> val > key) root -> left = deleteNode(root -> left, key);
if(root -> val < key) root -> right = deleteNode(root -> right, key);
return root;
}
};
代码虽然很多,只要慢慢分析是不难的,不能有畏难情绪。



















