给「代码随想录」一个星标吧!
❝
一些同学反馈文章中代码在手机上看不全。温馨提示:大家看代码的时候,代码块是可以左滑的!是可以左滑的!是可以左滑的!
题目链接:
给定一个二叉搜索树的根节点 root 和一个值 key,删除二叉搜索树中的 key 对应的节点,并保证二叉搜索树的性质不变。返回二叉搜索树(有可能被更新)的根节点的引用。
一般来说,删除节点可分为两个步骤:
首先找到需要删除的节点;如果找到了,删除它。说明:要求算法时间复杂度为 O(h),h 为树的高度。
示例:
450.删除二叉搜索树中的节点思路
搜索树的节点删除要比节点增加复杂的多,有很多情况需要考虑,做好心里准备。
递归三部曲:
说道递归函数的返回值,在中通过递归返回值来加入新节点递归写法, 这里也可以通过递归返回值删除节点。
代码如下:
遇到空返回,其实这也说明没找到删除的节点,遍历到空节点直接返回了
这里就把平衡二叉树中删除节点遇到的情况都搞清楚。
有以下五种情况:
第五种情况有点难以理解,看下面动画:
动画中颗二叉搜索树中,删除元素7, 那么删除节点(元素7)的左孩子就是5,删除节点(元素7)的右子树的最左面节点是元素8。
将删除节点(元素7)的左孩子放到删除节点(元素7)的右子树的最左面节点(元素8)的左孩子上,就是把5为根节点的子树移到了8的左孩子的位置。
要删除的节点(元素7)的右孩子(元素9)为新的根节点。.
这样就完成删除元素7的逻辑,最好动手画一个图,尝试删除一个节点试试。
代码如下:
这里相当于把新的节点返回给上一层,上一层就要用 root->left 或者 root->right接住,代码如下:
「整体代码如下:(注释中:情况1,2,3,4,5和上面分析严格对应)」
用普通二叉树的思路来删
这里我再介绍一种通用的删除,普通二叉树的删除方式(没有使用搜索树的特性,遍历整棵树),用交换值的操作来删除目标节点。
代码中目标节点(要删除的节点)被操作了两次:
思路有点绕,感兴趣的同学可以画图自己理解一下。
代码如下:(关键部分已经注释)
这个代码是简短一些,思路也巧妙,但是不太好想,实操性不强,推荐第一种写法!
迭代法
删除节点的迭代法还是复杂一些的,但其本质我在递归法里都介绍了,最关键就是删除节点的操作(动画模拟的过程)
代码如下:
总结
读完本篇,大家会发现二叉搜索树删除节点比增加节点复杂的多。
「因为二叉搜索树添加节点只需要在叶子上添加就可以的,不涉及到结构的调整,而删除节点操作涉及到结构的调整」。
这里我们依然使用递归函数的返回值来完成把节点从二叉树中移除的操作。
「这里最关键的逻辑就是第五种情况(删除一个左右孩子都不为空的节点),这种情况一定要想清楚」。
而且就算想清楚了递归写法,对应的代码也未必可以写出来,所以「这道题目即考察思维逻辑,也考察代码能力」。
递归中我给出了两种写法,推荐大家学会第一种(利用搜索树的特性)就可以了,第二种递归写法其实是比较绕的。
最后我也给出了相应的迭代法,就是模拟递归法中的逻辑来删除节点,但需要一个pre记录cur的父节点,方便做删除操作。
迭代法其实不太容易写出来,所以如果是初学者的话,彻底掌握第一种递归写法就够了。
「就酱,又是干货满满的一篇,顺便转发给身边需要的同学吧!」
———END———
限 时 特 惠:本站每日持续更新海量各大内部创业教程,一年会员只需128元,全站资源免费下载点击查看详情
站 长 微 信:jiumai99
2.本站所有项目来源于投稿或购买自其他第三方,若本站侵犯了您的权益请 联系站长 进行删除处理。