如何编写二进制搜索树删除代码?

时间:2016-12-01 19:49:31

标签: java binary-search-tree

我在使用BST时为removeNode()方法编写了以下伪代码:

If left is null
 Replace n with n.right
Else if n.right is null
 Replace n with n.left
Else
Find Predecessor of n
Copy data from predecessor to n
Recursively delete predecessor*

我不仅希望此方法删除或删除节点,而且如果删除成功,我还希望它返回true。

这是我到目前为止所写的内容,我想知道是否有人会有反馈,建议的更改或提示来帮助我完成该方法。我还将把我的整个程序附在此方法之下。

   private void removeNode(Node<E> n) {
      if (n.left == null) {
         replace(n, n.right);
      } else if (n.right == null) {
         replace(n, n.left);
      } else {
      //How do I find pred of n
      //Copy data from pred to n
      //Recursively delete pred
      }

   }

以下是我的其余代码:

import java.util.Random;

public class BinarySearchTree<E extends Comparable<? super E>> extends BinaryTree<E> {

   public boolean contains(E item) {
      return findNode(item, root) != null;
   }

   private Node<E> findNode(E item, Node<E> n) {
      if (n == null || item == null) return null;
      int result = item.compareTo(n.data);
      if (result == 0) {
         return n;
      } else if (result > 0) {
         return findNode(item, n.right);
      } else {
         return findNode(item, n.left);
      }
   }

   public E max() {
      Node<E> m = maxNode(root);
      return (m != null) ? m.data : null;
   }

   private Node<E> maxNode(Node<E> n) {
      if (n == null) return null;
      if (n.right == null) return n;
      return maxNode(n.right);
   }

   public E min() {
      Node<E> m = minNode(root);
      return (m != null) ? m.data : null;
   }

   private Node<E> minNode(Node<E> n) {
      if (n == null) return null;
      if (n.left == null) return n;
      return minNode(n.left);
   }

   public E pred(E item) {
      Node<E> n = findNode(item, root);
      if (n == null) return null;
      Node<E> pred = predNode(n);
      return (pred != null) ? pred.data : null;
   }

   private Node<E> predNode(Node<E> n) {
      assert n != null;
      if (n.left != null) return maxNode(n.left);
      Node<E> p = n.parent;
      while (p != null && p.left == n) {
         n = p;
         p = p.parent;         
      }
      return p;
   }

   public E succ(E item) {
      Node<E> n = findNode(item, root);
      if (n == null) return null;
      Node<E> succ = succNode(n);
      return (succ != null) ? succ.data : null;
   }

   private Node<E> succNode(Node<E> n) {
      assert n != null;
      if (n.right != null) return minNode(n.right);
      Node<E> p = n.parent;
      while (p != null && p.right == n) {
         n = p;
         p = p.parent;         
      }
      return p;
   }

   public void add(E item) {
      if (item == null) return;
      if (root == null) {
         root = new Node<>(item, null);
      } else {
         addNode(item, root);
      }
   }

   private void addNode(E item, Node<E> n) {
      assert item != null && n != null;
      int result = item.compareTo(n.data);
      if (result < 0) {
         if (n.left == null) {
            n.left = new Node<>(item, n);
         } else {
            addNode(item, n.left);
         }
      } else if (result > 0) {
         if (n.right == null) {
            n.right = new Node<>(item, n);
         } else {
            addNode(item, n.right);
         }
      } else {
         return;  // do not add duplicates
      }
   }


   public boolean remove(E item) {
      Node<E> n = findNode(item, root);
      if (n == null) return false;
      removeNode(n);
      return true;
   }

   private void removeNode(Node<E> n) {
      if (n.left == null) {
         replace(n, n.right);
      } else if (n.right == null) {
         replace(n, n.left);
      } else {
      //How do I find pred of n
      //Copy data from pred to n
      //Recursively delete pred
      }

   }

   private void replace(Node<E> n, Node<E> child) {
      assert n != null;
      Node<E> parent = n.parent;
      if (parent == null) {
         root = child;
      } else if (parent.left == n) {
         parent.left = child;
      } else {
         parent.right = child;
      }
      if (child != null) child.parent = parent;
   }


   public String toString() {
      return inorder();
   }

1 个答案:

答案 0 :(得分:0)

删除元素的代码非常简单。

  1. 搜索要删除的节点。
  2. 检查节点是否有子节点。
  3. 案例1 - 只留下孩子 - &gt;用左子项替换当前节点。
  4. 案例2 - 只有正确的孩子 - &gt;用正确的孩子替换当前节点。
  5. 案例3 - 有两个孩子 - &gt;找到右子子树中的最小元素,用该节点替换当前节点,然后删除该节点。
  6. 代码可以递归实现,如下所示 - &gt;

    BinarySearchTree.prototype.remove = function(data) {
    var that = this;
    var remove = function(node,data){
       if(node.data === data){
           if(!node.left && !node.right){
               return null;
           }
           if(!node.left){
               return node.right;
           }
           if(!node.right){
               return node.left;
           }
           //2 children
           var temp = that.findMin(node.right);
           node.data = temp;
           node.right = remove(node.right,temp);
    
        }else if(data < node.data){
            node.left = remove(node.left,data);
            return node;
        }else{
            node.right = remove(node.right,data);
            return node;
        }
      };
     this.root = remove(this.root,data);
    };