235.二叉搜索树的最近公共祖先
题目链接:二叉搜索树的最近公共祖先
题目描述:
给定一个二叉搜索树, 找到该树中两个指定节点的最近公共祖先。
百度百科中最近公共祖先的定义为:“对于有根树 T 的两个结点 p、q,最近公共祖先表示为一个结点 x,满足 x 是 p、q 的祖先且 x 的深度尽可能大(一个节点也可以是它自己的祖先)。”
解题思路:
- 这题完全可以用上题的代码进行,毕竟二叉搜索树也是二叉树。
- 可以用上二叉搜索的特性来解题。如果目前点的值,大于pq两个点的值,说明,pq两节点在其左子树中,如果目前点的值,大于其中一个小于另一个,说明该点就是最近公共祖先了,如果小于两个节点的值,说明,在其右子树上。
class Solution {
public:
TreeNode* lowestCommonAncestor(TreeNode* root, TreeNode* p, TreeNode* q) {
return traversal(root,p,q);
}
TreeNode* traversal(TreeNode* cur,TreeNode* p,TreeNode* q)
{
if(cur==NULL) return cur;
if(cur->val>p->val&&cur->val>q->val)
{
TreeNode* left=traversal(cur->left,p,q);
if(left!=NULL) return left;
}
if(cur->val<p->val&&cur->val<q->val)
{
TreeNode* right=traversal(cur->right,q,p);
if(right!=NULL) return right;
}
return cur;
}
};
701.二叉搜索树中的插入操作
题目链接:二叉搜索树中的插入操作
题目描述:
给定二叉搜索树(BST)的根节点 root 和要插入树中的值 value ,将值插入二叉搜索树。 返回插入后二叉搜索树的根节点。 输入数据 保证 ,新值和原始二叉搜索树中的任意节点值都不同。
注意,可能存在多种有效的插入方式,只要树在插入后仍保持为二叉搜索树即可。 你可以返回 任意有效的结果 。
解题思路:
- 通过中序遍历找到相应的位置,新建一个节点插入即可。
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;
}
};
450.删除二叉搜索树中的节点
题目链接:删除二叉搜索树中的节点
题目描述:
给定一个二叉搜索树的根节点 root 和一个值 key,删除二叉搜索树中的 key 对应的节点,并保证二叉搜索树的性质不变。返回二叉搜索树(有可能被更新)的根节点的引用。
一般来说,删除节点可分为两个步骤:
首先找到需要删除的节点;
如果找到了,删除它。
解题思路:
删除节点,主要有以下五种可能性
- 未找到该节点
- 是叶子节点,直接删除即可
- 只有左孩子,没有右孩子
- 只有右孩子,没有左孩子
- 左右孩子都有,需要把原节点的左孩子放到右子树的最左孩子后面
/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode() : val(0), left(nullptr), right(nullptr) {}
* TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
* TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}
* };删除节点操作,主要有以下几个情况
1. 是叶子节点,直接删除即可
2.不是叶子节点,只有左子树,把左子树往上
3.不是叶子节点,只有右子树,把右子树往上
4.不是叶子结点,但是左右孩子都有,需要把原节点的左孩子放到右子树的最左孩子后面
5.没找到
*/
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 nullptr;
}
else if(root->left!=NULL&&root->right==NULL)
{
TreeNode* left=root->left;
delete root;
return left;
}
else if(root->right!=NULL&&root->left==NULL)
{
TreeNode* right=root->right;
delete root;
return right;
}
else if(root->right!=NULL&&root->left!=NULL)
{
TreeNode* node=root->right;
while(node->left)
{
node=node->left;
}
node->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;
}
};