代码随想录刷题随记19-二叉树8
235. 二叉搜索树的最近公共祖先
leetcode
因为是有序树,所以 如果 中间节点是 q 和 p 的公共祖先,那么 中节点的数组 一定是在 [p, q]区间的。即 中节点 > p && 中节点 < q 或者 中节点 > q && 中节点 < p
注意这里必须先访问根节点,后序遍历不行
解题代码
class Solution {
public:TreeNode* lowestCommonAncestor(TreeNode* root, TreeNode* p, TreeNode* q) {TreeNode * cur;stack<TreeNode* >mystack;mystack.push(root);while(!mystack.empty()){cur=mystack.top();mystack.pop();if(cur==p||cur==q)return cur;if((cur->val>p->val&&cur->val<q->val)||(cur->val<p->val&&cur->val>q->val))return cur;if(cur->right!=nullptr)mystack.push(cur->right);if(cur->left!=nullptr)mystack.push(cur->left); } return nullptr;}
};
701.二叉搜索树中的插入操作
leetcode链接
只要遍历二叉搜索树,找到空节点 插入元素就可以了,并不需要调整树的结构
class Solution {
public:TreeNode* insertIntoBST(TreeNode* root, int val) {if(root==nullptr)return new TreeNode(val);TreeNode * cur=root;TreeNode * pre=nullptr;while(cur!=nullptr){pre=cur;
… pre->right=new TreeNode (val);return root;}
};
450.删除二叉搜索树中的节点
leetcode链接
与插入不同,删除节点涉及到修改树的结构
有点类似于两个搜索树要合并的意思
解题代码
在这里插入代码片
有以下五种情况:
第一种情况:没找到删除的节点,遍历到空节点直接返回了
找到删除的节点
第二种情况:左右孩子都为空(叶子节点),直接删除节点, 返回NULL为根节点
第三种情况:删除节点的左孩子为空,右孩子不为空,删除节点,右孩子补位,返回右孩子为根节点
第四种情况:删除节点的右孩子为空,左孩子不为空,删除节点,左孩子补位,返回左孩子为根节点
第五种情况:左右孩子节点都不为空,则将删除节点的左子树头结点(左孩子)放到删除节点的右子树的最左面节点的左孩子上,返回删除节点右孩子为新的根节点。
class Solution {
public:TreeNode * subdel(TreeNode * cur){if(cur==nullptr)return nullptr;if(cur->left==nullptr&&cur->right==nullptr)return nullptr;if(cur->left==nullptr)return cur->right;if(cur->right==nullptr)return cur->left;TreeNode * tmp=cur->right;while(tmp->left){tmp=tmp->left;}tmp->left=cur->left;tmp=cur;cur=cur->right;tmp->right=nullptr;tmp->left=nullptr;delete tmp;return cur;}TreeNode* deleteNode(TreeNode* root, int key) {TreeNode * cur=root;TreeNode * pre=nullptr;if(root==nullptr)return nullptr;while(cur!=nullptr){ if(cur->val==key)break;pre=cur;if(cur->val<key)cur=cur->right;else cur=cur->left;}//没找到if(cur==nullptr){return root;}//要删除的是根节点if(pre==nullptr)return subdel(root);if(pre->left==cur){pre->left=subdel(cur);}else if(pre->right==cur){pre->right=subdel(cur);}return root;}};