节点删除

节点删除

老师您好  public的remove中已经找到了待删键值key对应的节点 ,private的remove中 是不是可以修改一下,直接传入待删除节点,直接删除,不再递归寻找

正在回答

登陆购买课程后可参与讨论,去登陆

1回答

如果你是指 getNode 和 remove 这实际上在 BST 上走了两趟的话,是的,这两趟是可以合一的。


实际上,在之前,我们学习的使用 BST 实现的 Set,在这里就只有一趟遍历。 但是为什么 Map 我写了两趟?是因为我们的 remove 的函数设计,除了删除节点这个动作之外,还需要返回待删除节点的 Value。而我们的 remove 动作,需要返回对当前子树执行完删除操作后的新的子树的根节点。因此,我们在递归的过程中,需要记录两个值。


使用两趟遍历,其实是每一趟处理一件事情,简化了这个问题。(但损失了性能,不过整体性能依然是 logn 的)。


如果你想一趟处理,使用 getNode 找到待删除节点后,直接对这个节点做事情是不可以的。因为对待删除节点的操作,可能影响这个节点的父亲节点,所以,仅仅有这个待删除节点是不够的。(对于 BST 来说,如果有父亲节点就够了。但是,后续的 AVL 树,你会看到,一个删除动作,有可能影响待删除节点的所有祖先节点。)


(或者我不确定你的描述是不是其实你自己有思考可以如何实现,但是我没有理解。你可以尝试用代码来实现一下。这是很好的一个练习:))



如果你想一趟解决这个问题,有两个思路:


1)在 remove 的过程中,多传入一个 Node 类型的节点,记录待删除节点。这是最简单的;


2)将 remove 的过程修改为返回两个参数。Java 原生不支持多参数函数,可以靠返回一个 Pair 来解决。



继续加油!:)

  • 老师,您好,这里我有一个疑问 。对于第一种思路 ”在 remove 的过程中,多传入一个 Node 类型的节点,记录待删除节点“,本质就是把返回值放在参数位置吧,就像generateBSTString(Node node, int depth, StringBuilder res),StringBuilder res在toString()中声明。但是针对java语言,参数是按“引用传递“,所以使用多传入一个参数的方式,需要把Node节点用一个类封装起来吧。不知道我想到是否正确?也许老师说的是其他的和我想得不同的方法。

    2021-12-13 17:05:32
  • 你说的是正确的,在这里我只是说一个思路,如果是细节的话,这个说法不严谨。或者还需要传入待删除节点的父亲节点;或者在 BST 的 Node 中要维护每一个节点的父亲节点,这样传入待删除节点以后,可以找到其父亲节点,正确完成删除。(印象中 JDK 中的红黑树(TreeMap,TreeSet)的 Node 都维护了父亲节点信息,对比 JDK 中的链表也是双向链表,就是方便类似这样的操作。)

    2021-12-13 17:10:59
  • 感谢老师的回复

    2021-12-14 08:42:59
问题已解决,确定采纳
还有疑问,暂不采纳

恭喜解决一个难题,获得1积分~

来为老师/同学的回答评分吧

0 星
算法与数据结构
  • 参与学习       2583    人
  • 解答问题       1082    个

慕课网算法名师Liuyubobobo,5年集大成之作 从0到工作5年,算法与数据结构系统解决方案

了解课程
请稍等 ...
意见反馈 帮助中心 APP下载
官方微信

在线咨询

领取优惠

免费试听

领取大纲

扫描二维码,添加
你的专属老师