代码随想录算法训练营第十九天| 235. 二叉搜索树的最近公共祖先 701.二叉搜索树中的插入操作 450.删除二叉搜索树中的节点

235. 二叉搜索树的最近公共祖先

思路:

因为是二叉搜索树,所以公共祖先一定是位于这两个节点区间中的

问题:

为什么第一个是这两个中间的例子,就是公共祖先呢?因为是最先符合要求的,

代码:

 1 TreeNode* lowestCommonAncestor(TreeNode* root, TreeNode* p, TreeNode* q)
 2 {
 3     if (!root) return NULL;
 4     if (root == p || root == q) return root;
 5 
 6     TreeNode* left = NULL, * right = NULL;
 7     if (root->left) left = lowestCommonAncestor(root->left, p, q);
 8     if (root->right) right = lowestCommonAncestor(root->right, p, q);
 9 
10     if (left && right) return root;
11     else if (!left && right) return right;
12     else if (!right && left) return left;
13     else return NULL;
14 }

 701.二叉搜索树中的插入操作

思路:

先找到左右两个节点,如果左节点不存在, 右-左, 如果左节点存在 右不存在,那么就 左-右

代码:

 1 TreeNode* insertIntoBST(TreeNode* root, int val) {
 2     TreeNode* newNode = new TreeNode(val);
 3     if (!root)return newNode;
 4 
 5     TreeNode* left = NULL, * right = NULL;
 6     int leftSub = INT_MAX, rightSub = INT_MAX;
 7 
 8     stack<TreeNode*> selected;
 9     selected.push(root);
10     //找出<0最大的节点 和>0最小的节点 也就是他们差值绝对值最小的节点
11     while (!selected.empty())
12     {
13         auto cur_ = selected.top(); selected.pop();
14 
15         int val_ = cur_->val - val;
16         if (val_ < 0 && abs(leftSub) > abs(val_))
17         {
18             leftSub = val_;
19             left = cur_;
20         }
21         else if(val_ > 0 && abs(rightSub) > abs(val_))
22         {
23             rightSub = val_;
24             right = cur_;
25         }
26 
27         if (cur_->left) selected.push(cur_->left);
28         if (cur_->right) selected.push(cur_->right);
29     }
30 
31     //现在需要判断这两个节点, 左节点的右节点,或者右节点的左节点
32     
33     if (left&&right)
34     {
35         if (!left->right) left->right = newNode;
36         else if (!right->left) right->left = newNode;
37     }
38     else if (left && !right)
39     {
40         left->right = newNode;
41     }
42     else if (!left && right)
43     {
44         right->left = newNode;
45     }
46     return root;
47 }

 最简单的方法,

我们只关注叶子节点,如果当前节点为空,那么 就是目标节点,如果不为空,那么就返回本节点

因为他是一路追寻,所以不会出现给其他节点赋值的情况

代码:

 1 TreeNode* insertIntoBST(TreeNode* root, int val) {
 2     TreeNode* newNode = new TreeNode(val);
 3     if (!root)return newNode;
 4     
 5     if (root->val < val)
 6     {
 7         root->right = insertIntoBST(root->right, val);
 8     }
 9     else
10     {
11         root->left = insertIntoBST(root->left, val);
12     }
13     return root;
14 }

 450.删除二叉搜索树中的节点  

思路:

找到当前节点后,删掉当前节点,不要想如果我删掉当前节点,那么它的父节点怎么办?

我直接把当前的节点设置为NULL,那么它的父节点指向的也就是NULL,所以不用着急

怎么删去有左右孩子的节点:直接把左子树所有都放到右子树的最左边,就可以了

代码:

 1 TreeNode* deleteNode(TreeNode* root, int key) {
 2     if (!root) return NULL;
 3 
 4     if (root->val == key)
 5     {
 6         if (!root->left && !root->right)
 7         {
 8             return NULL;
 9         }
10         if (root->left && !root->right)
11         {
12             return root->left;
13         }
14         if (!root->left && root->right)
15         {
16             return root->right;
17         }
18         if (root->right && root->left)
19         {
20             auto cur_ = root->right;
21 
22             while (cur_->left != NULL)
23             {
24                 cur_ = cur_->left;
25             }
26 
27             cur_->left = root->left;
28             return root->right;
29         }
30     }
31 
32     if (root->val > key)
33     {
34         root->left = deleteNode(root->left, key);
35     }
36     if (root->val < key)
37     {
38         root->right = deleteNode(root->right, key);
39     }
40 
41     return root;
42 }

 

posted @ 2023-06-28 11:51  博二爷  阅读(4)  评论(0编辑  收藏  举报