递归法

1、确定递归函数的参数和返回值
说到递归函数的返回值,在⼆叉树:搜索树中的插⼊操作中通过递归返回值来加⼊新节点, 这⾥也可以通过递归返回值删除节点。

TreeNode* deleteNode(TreeNode* root,int key);

2、确定终止条件
遇到空返回,说明没有找到删除的节点

if(root==nullptr) return root;

3、确定单层递归的逻辑
删除节点会遇到5种情况:
第⼀种情况:没找到删除的节点,遍历到空节点直接返回了

找到删除的节点:
第⼆种情况:左右孩⼦都为空(叶⼦节点),直接删除节点, 返回NULL为根节点
第三种情况:删除节点的左孩⼦为空,右孩⼦不为空,删除节点,右孩⼦补位,返回右孩⼦为根节点
第四种情况:删除节点的右孩⼦为空,左孩⼦不为空,删除节点,左孩⼦补位,返回左孩⼦为根节点
第五种情况:左右孩⼦节点都不为空,则将删除节点的左⼦树头结点(左孩⼦)放到删除节点的右⼦树的最左⾯节点的左孩⼦上,返回删除节点右孩⼦为新的根节点。

if (root->val == key) {// 第二种情况:左右孩子都为空(叶子节点),直接删除节点, 返回NULL为根节点// 第三种情况:其左孩子为空,右孩子不为空,删除节点,右孩子补位 ,返回右孩子为根节点if (root->left == nullptr) return root->right; // 第四种情况:其右孩子为空,左孩子不为空,删除节点,左孩子补位,返回左孩子为根节点else if (root->right == nullptr) return root->left; // 第五种情况:左右孩子节点都不为空,则将删除节点的左子树放到删除节点的右子树的最左面节点的左孩子的位置// 并返回删除节点右孩子为新的根节点。else {  TreeNode* cur = root->right; // 找右子树最左面的节点while(cur->left != nullptr) { cur = cur->left;}cur->left = root->left; // 把要删除的节点(root)左子树放在cur的左孩子的位置TreeNode* tmp = root;   // 把root节点保存一下,下面来删除root = root->right;     // 返回旧root的右孩子作为新rootdelete tmp;             // 释放节点内存(这里不写也可以,但C++最好手动释放一下吧)return root;}
}

完整递归

class Solution {public:TreeNode* deleteNode(TreeNode* root, int key) {if (root == nullptr) return root; // 第一种情况:没找到删除的节点,遍历到空节点直接返回了if(root->val==key){//5皇帝要杀一个犯错的士兵3,士兵被送入断头台(delete函数),在临死之前,士兵把自己的孩子返回交给皇帝来继承自己的位置if(root->left==nullptr) return root->right;if(root->right==nullptr) return root->left;else {TreeNode* cur=root->right;while(cur->left!=nullptr){cur=cur->left;}cur->left=root->left;return root->right;}} //皇帝root要找到犯错士兵key并处置它if(key<root->val) root->left=deleteNode(root->left,key);if(key>root->val) root->right=deleteNode(root->right,key);return root;}
};

大家画图就会发现上面的代码其实是有数据冗余的。那么我们可以接着优化下:

class Solution {public:TreeNode* deleteNode(TreeNode* root, int key) {if (root == nullptr) return root; // 第一种情况:没找到删除的节点,遍历到空节点直接返回了if (root->val == key) {// 第二种情况:左右孩子都为空(叶子节点),直接删除节点, 返回NULL为根节点//可省略if(root->left==nullptr&&root->right==nullptr) return NULL;// 第三种情况:其左孩子为空,右孩子不为空,删除节点,右孩子补位 ,返回右孩子为根节点if (root->left == nullptr) return root->right; // 第四种情况:其右孩子为空,左孩子不为空,删除节点,左孩子补位,返回左孩子为根节点else if (root->right == nullptr) return root->left; // 第五种情况:左右孩子节点都不为空,则将删除节点的左子树放到删除节点的右子树的最左面节点的左孩子的位置// 并返回删除节点右孩子为新的根节点。else {  TreeNode* cur = root->right; // 找右子树最左面的节点while(cur->left != nullptr) { cur = cur->left;}cur->left = root->left; // 把要删除的节点(root)左子树放在cur的左孩子的位置TreeNode* tmp = root;   // 把root节点保存一下,下面来删除root = root->right;     // 返回旧root的右孩子作为新rootdelete tmp;             // 释放节点内存(这里不写也可以,但C++最好手动释放一下吧)return root;}}if (root->val > key) root->left = deleteNode(root->left, key);if (root->val < key) root->right = deleteNode(root->right, key);return root;}
};

最终版

class Solution {public:TreeNode* deleteNode(TreeNode* root, int key) {if (root == nullptr) return root; // 第一种情况:没找到删除的节点,遍历到空节点直接返回了if(root->val==key){//5皇帝要杀一个犯错的士兵3,士兵被送入断头台(delete函数),在临死之前,士兵把自己的孩子返回交给皇帝来继承自己的位置if(root->left==nullptr) {TreeNode* temp=root;root=root->right;delete temp; return root;}if(root->right==nullptr) {TreeNode* temp=root;root=root->left;delete temp;return root;}else {  TreeNode* cur = root->right; // 找右子树最左面的节点while(cur->left != nullptr) { cur = cur->left;}cur->left = root->left; // 把要删除的节点(root)左子树放在cur的左孩子的位置TreeNode* tmp = root;   // 把root节点保存一下,下面来删除root = root->right;     // 返回旧root的右孩子作为新rootdelete tmp;             // 释放节点内存(这里不写也可以,但C++最好手动释放一下吧)return root;}}if (root->val > key) root->left = deleteNode(root->left, key);if (root->val < key) root->right = deleteNode(root->right, key);return root;}
};

删除二叉搜索树中的节点相关推荐

  1. LeetCode450题—— 删除二叉搜索树中的节点

    首先需要认识什么是二叉搜索树,可以进入百度词条https://baike.baidu.com/item/%E4%BA%8C%E5%8F%89%E6%90%9C%E7%B4%A2%E6%A0%91/70 ...

  2. ​LeetCode刷题实战450:删除二叉搜索树中的节点

    算法的重要性,我就不多说了吧,想去大厂,就必须要经过基础知识和业务逻辑面试+算法面试.所以,为了提高大家的算法能力,这个公众号后续每天带大家做一道算法题,题目就从LeetCode上面选 ! 今天和大家 ...

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

    文章目录 LeetCode 236. 二叉树的最近公共祖先 题目讲解 思路 LeetCode 701.二叉搜索树中的插入操作 题目讲解 思路 LeetCode 450.删除二叉搜索树中的节点 题目讲解 ...

  4. 二叉树part8 | ● 235. 二叉搜索树的最近公共祖先 ● 701.二叉搜索树中的插入操作 ● 450.删除二叉搜索树中的节点

    文章目录 235. 二叉搜索树的最近公共祖先 思路 代码 困难 701.二叉搜索树中的插入操作 思路 代码 450.删除二叉搜索树中的节点 思路 代码 困难 今日收获 235. 二叉搜索树的最近公共祖 ...

  5. leetcode 450. 删除二叉搜索树中的节点 c语言实现

    如题: 给定一个二叉搜索树的根节点 root 和一个值 key,删除二叉搜索树中的 key 对应的节点,并保证二叉搜索树的性质不变.返回二叉搜索树(有可能被更新)的根节点的引用. 一般来说,删除节点可 ...

  6. 67. Leetcode 450. 删除二叉搜索树中的节点 (二叉搜索树-基本操作类)

    给定一个二叉搜索树的根节点 root 和一个值 key,删除二叉搜索树中的 key 对应的节点,并保证二叉搜索树的性质不变.返回二叉搜索树(有可能被更新)的根节点的引用.一般来说,删除节点可分为两个步 ...

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

    给定一个二叉搜索树的根节点 root 和一个值 key,删除二叉搜索树中的 key 对应的节点,并保证二叉搜索树的性质不变.返回二叉搜索树(有可能被更新)的根节点的引用. 一般来说,删除节点可分为两个 ...

  8. 【数据结构与算法】之深入解析“删除二叉搜索树中的节点”的求解思路与算法示例

    一.题目要求 给定一个二叉搜索树的根节点 root 和一个值 key,删除二叉搜索树中的 key 对应的节点,并保证二叉搜索树的性质不变,返回二叉搜索树(有可能被更新)的根节点的引用. 一般来说,删除 ...

  9. java 递归从子节点删除父节点_LeetCode450. 删除二叉搜索树中的节点

    删除一个二叉搜索树中的节点,需要进行情况的分类讨论,看一下将这个节点删除之后是否需要对二叉搜索树进行调整(为了保持树的连接和维持二叉搜索树的性质). (1)如果删除的是一个叶子节点,那问题不大,因为它 ...

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

    给定一个二叉搜索树的根节点 root 和一个值 key,删除二叉搜索树中的 key 对应的节点,并保证二叉搜索树的性质不变.返回二叉搜索树(有可能被更新)的根节点的引用. 一般来说,删除节点可分为两个 ...

最新文章

  1. margin和padding
  2. 百度神马搜狗360网站地图sitemap,主动提交推送插件
  3. DEV ImageComboxEdit 使用
  4. 动手开始创建第一个 Angular 应用并通过 gh-pages 发布到 Github 上
  5. python 创建子类_python创建子类的方法分析
  6. Response.Redirect 编码的问题
  7. SuperSpider——打造功能强大的爬虫利器
  8. 李善友:为什么外企人不敢创业
  9. And Design:拓荒笔记——Form表单
  10. 杭电1754I Hate It 线段树与非线段树
  11. Charles抓包基本应用
  12. python使用win32*模块模拟人工操作——城通网盘下载器(一)
  13. 家用电脑如何安装服务器系统,普通电脑安装服务器系统
  14. 小程序源码:修复登录接口版最新知识付费变现小程序源码下载-独立后台版本
  15. STM32CubeMX实现串口DMA中断通信
  16. 上面两点下面一个三角形_三角形光栅化
  17. windows添加右键点击打开CMD(运行)的方法
  18. 测试点击屏幕次数的软件_无需越狱,iOS 任意摆放主屏幕软件图标方法
  19. gsm模块 java 录音_Arduino从Quectel M95 GSM模块读取AT命令
  20. PageHelper关联查询 统计总数问题

热门文章

  1. Java多线程与并发库高级应用 学习笔记 1-9课
  2. Web.xml配置详解之context-param(转)
  3. 黑顶帽—lhMorpBlackTopHat
  4. web安全_皮卡丘_csrf
  5. iOS之深入解析weak关键字的底层原理
  6. iOS之深入解析预乘透明度Premultiplied Alpha
  7. LeetCode Algorithm 572. 另一棵树的子树
  8. 手把手教你完成CSDN对接百度统计 看完这篇文章你还不会对接 欢迎您提刀顺着网线来砍我!!!!
  9. 数据库开发——MySQL——foreign key
  10. 信息学奥赛一本通(C++)在线评测系统——基础(一)C++语言——1089:数字反转