关于《算法导论》中二叉树的删除算法

  先简单介绍一下二叉查找树吧,二叉查找树就是具有左子树的任一结点都不大于根结点,右子树的任一结点都不小于根结点这一性质的二叉树。对于它删除一个结点的算法,书上是分三种情况讨论的。

  首先,要删除的结点z没有儿子,这种情况很简单,z是它父亲结点的哪个儿子,就让指向那个儿子的指针指空,z指向父亲结点的指针指空就可以了。

  其次,要删除的结点z只有一个儿子,那么以z为根结点的子树,要么都不大于z的父亲结点,要么都不小于z的父亲结点,这时候让z的儿子中指向z的指针改指向z的父亲结点,z是它父亲结点的哪个儿子,就让指向那个儿子的指针指向z的儿子,再处理一下z的指针就可以了。

  最后,最删除的结点z有两个儿子,这种情况是最复杂的,书上给出的方法是先让z的后继y替代z,然后修改y父亲结点的指针,使之指向y唯一的儿子或NULL(这种情况下z的后继肯定至多有一个儿子),书上对于用z的后继y替代z的处理是key[z]=key[y],这样做,无需改变原来z结点的指向其他结点指针了,但是我认为这样做在某些情况下是不妥的,比如结点中卫星数据量很大的时候,这样做无非增大了时间和内存的开销,还有当结点中卫星数据是只读属性的情况下,无法改写z中的卫星数据,所以我认为最妥当的做法,应该是改变y的指针,使之分别指向z的父亲结点,儿子结点。

  以上的算法是《算法导论》原书第2版在156页提出的算法,查阅了一下《Introduction to Algorithms》Third Edition,提出了一种改进的算法,先介绍transplant(T,u,v)函数,该函数的功能是将以v为根结点的树替代以u为根结点的树,有了transplant函数,delete算法有了更容易的实现方法:

  1. z有至多一个儿子,那就用那颗子树(可以是NULL)去替代z子树;
  2. z有两个儿子,先用z后继y的子树替代以y为根结点的子树,然后再通过改变指针让y去替代z
  3. 总结一下两种方法,其实道理都是一样的,形式不同,后面的那种方法更严谨一些。
    原文作者:FingerDancing
    原文地址: https://www.cnblogs.com/fingerdancing/archive/2013/04/14/binTree.html
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞