Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/380.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/heroku/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 红黑树删除_Java_Tree_Binary Tree_Red Black Tree - Fatal编程技术网

Java 红黑树删除

Java 红黑树删除,java,tree,binary-tree,red-black-tree,Java,Tree,Binary Tree,Red Black Tree,我在编写红黑树删除函数(使用Sentinel)时遇到问题 经过数小时的故障排除,我得出结论,问题出现在以下步骤中: 插入14、11、7和8,然后删除11(根) 11被没有孩子的14所取代。然后,x(参见代码)获取NULL节点的值-这使得像x.parent这样的函数毫无意义(对吗?) 然后程序在一个空异常中停止 你知道有什么问题吗 *我希望我已经把自己说清楚了——如果不是的话,我很乐意提供更多的信息 谢谢 完整的相关代码: public class RBTree { private RB

我在编写红黑树删除函数(使用Sentinel)时遇到问题

经过数小时的故障排除,我得出结论,问题出现在以下步骤中:

插入14、11、7和8,然后删除11(根)

11被没有孩子的14所取代。然后,x(参见代码)获取NULL节点的值-这使得像x.parent这样的函数毫无意义(对吗?)

然后程序在一个空异常中停止

你知道有什么问题吗

*我希望我已经把自己说清楚了——如果不是的话,我很乐意提供更多的信息

谢谢

完整的相关代码:

public class RBTree {

    private RBNode DUMMYROOT;
    private RBNode NULL;
    private int numOfNodes;


    public RBTree() {
        this.numOfNodes=0;
        this.NULL = new RBNode();
        this.DUMMYROOT = new RBNode();

        this.DUMMYROOT.setKey(Double.POSITIVE_INFINITY);
        this.DUMMYROOT.setLeftChild(NULL);
        this.DUMMYROOT.setColor("black");
        this.NULL.setColor("black");

    }

    public RBNode getNULL() {
        return this.NULL;
    }

  /**
   * public boolean empty()
   * 
   * returns true if and only if the tree is empty
   *  
   */


  public boolean empty() {
    if (this.numOfNodes==0)
        return true;
    return false;
  }

  /**
   * public boolean search(int i)
   * 
   * returns true if and only if the tree contains i
   *  
   */
  public boolean search(double i) {
      return (recursiveSearch(i, this.DUMMYROOT.getLeftChild())!=NULL);
  }

  public RBNode searchNode(double i) {
      return recursiveSearch(i, this.DUMMYROOT.getLeftChild());
  }


  private RBNode recursiveSearch(double i, RBNode rbNode) {
      if (rbNode==NULL)
          return NULL;
      else if (rbNode.getKey()==i)
          return rbNode;
      else if (rbNode.getKey()<i)
          return recursiveSearch(i,rbNode.getRightChild());
      else
          return recursiveSearch(i,rbNode.getLeftChild());
}

/**
   * public void insert(int i)
   * 
   * inserts the integer i into the binary tree; the tree
   * must remain valid (keep its invariants).
   * the function returns the number of color flips, or 0 if i was already in the tree
   * 
   */
  public int insert(int i) {
       RBNode rb = new RBNode(i);
       if (this.search((double)i)==false) {
           this.numOfNodes++;
           return RBTreeInsert(this,rb);
       }
       return 0;
  }

  private RBNode treePosition(RBNode x, double k) {
       RBNode y=x;
       while (x!=NULL) {
          y=x;
          if (x.getKey()==k)
              return x;
          else if (x.getKey()>k)
              x=x.getLeftChild();
          else
              x=x.getRightChild();
       }
       return y;
  }

  private int RBTreeInsert(RBTree t, RBNode z) {
       RBNode y;
       y=treePosition(t.DUMMYROOT,z.getKey());
       if (z.getKey()!=y.getKey()) {
           z.setParent(y);
           z.setLeftChild(NULL);
           z.setRightChild(NULL);
           z.setColor("red");
           if (z.getKey()<y.getKey())
               y.setLeftChild(z);
           else
               y.setRightChild(z);
       }
       return RBTreeInsertFixUp(z,t);
  }


   private int RBTreeInsertFixUp(RBNode node, RBTree t) {

       int counter =0;

       if(this.empty()==true)
               return counter;

       while(node.parent.color.equals("red")){
        if(node.parent == node.parent.parent.leftChild){
            RBNode y = node.parent.parent.rightChild;

            //case 1
            if(y.color.equals("red")){
                counter+=3;
                node.parent.setColor("black");
                y.setColor("black");
                node.parent.parent.setColor("red");
                node = node.parent.parent;
            }

            //case 2
            else {
                if(node == node.parent.rightChild) {
                    node = node.parent;
                    leftRotate(node, t);
                }
            //case 3
                counter+=2;
                node.parent.setColor("black");
                node.parent.parent.setColor("red");
                rightRotate(node.parent.parent, t);
            }

        }

        else {
            RBNode y = node.parent.parent.leftChild;

            //case 1
            if(y.color.equals("red")){
                counter+=3;
                node.parent.setColor("black");
                y.setColor("black");
                node.parent.parent.setColor("red");
                node = node.parent.parent;
            }

            //case 2
            else {
                if (node == node.parent.leftChild) {
                    node = node.parent;
                    rightRotate(node, t);
                }
            //case 3
                counter+=2;
                node.parent.setColor("black");
                node.parent.parent.setColor("red");
                leftRotate(node.parent.parent, t);
            }

        }
    }

    if(!(this.DUMMYROOT.leftChild.color.equals("black"))) {
        this.DUMMYROOT.leftChild.setColor("black");
        counter++;
    }

    return counter;


}

    private void rightRotate(RBNode node, RBTree t) {
            RBNode y = node.leftChild;
            Transplant(node, y);
            leftChild(node, y.rightChild);
            rightChild(y, node);
        }

    private void leftRotate(RBNode node, RBTree t) {
            RBNode y = node.rightChild;
            Transplant(node,y);
            rightChild(node, y.leftChild);
            leftChild(y,node);

            }

    private void Transplant(RBNode node, RBNode y) {
            if(node == node.parent.leftChild)
                leftChild(node.parent, y);
            else
                rightChild(node.parent,y);
        }

    private void rightChild(RBNode node, RBNode y) {
            node.rightChild =y;
            y.parent = node;

    }

    private void leftChild(RBNode node, RBNode y) {
            node.leftChild = y;
            y.parent = node;

        }


  /**
   * public void delete(int i)
   * 
   * deletes the integer i from the binary tree, if it is there;
   * the tree must remain valid (keep its invariants).
   * the function returns the number of color flips, or 0 if i was not in the tree
   * 
   */
   public int delete(int i)
   {
       if (this.search(i)==true) {
           //deletion will be made, so we decrease numOfNodes by 1
           this.numOfNodes--;
           return RBTreeDelete(this.searchNode(i),this);
       }
       return 0;
   }

   public int RBTreeDelete(RBNode deleteNode, RBTree tree){

       RBNode y;
       RBNode x;

       if(this.empty() == true)
           return 0;

       if(deleteNode.getLeftChild() == this.NULL || deleteNode.getRightChild() == this.NULL)
           y = deleteNode;
       else {
           y = TreeSuccessor(deleteNode); 

       }

       if(y.leftChild != NULL)
           x = y.leftChild;
       else
           x = y.rightChild;

       x.parent = y.parent;
       if(y.parent == NULL)
           DUMMYROOT.leftChild = x;
       else if(y == y.parent.leftChild)
           y.parent.leftChild = x;
       else
           y.parent.rightChild = x;

       if(y != deleteNode)
           deleteNode.key = y.key;

       if (y.color.equals("black")==true) 
               return RBDeleteFixUp(tree, x);

       return 0; //counter is 0, no color changes should be made. if me made any - they will be returned by "RBDleteFixUp"
   }

   private int RBDeleteFixUp(RBTree T, RBNode x) {
       //counts color changes
       int counter2= 0;
       boolean b=true;
       RBNode w = new RBNode();

       if(this.empty()==true)
           return counter2;

       while(((x != DUMMYROOT.leftChild)) &&  x.color.equals("black") && b==true){
           if(x == x.parent.leftChild){
               w = x.parent.rightChild;
               //case 1
               if(w.color.equals("red")){
                   System.out.println("1");

                   w.setColor("black");
                   counter2++;
                   x.parent.setColor("red");
                   counter2++;
                   leftRotate(x.parent, T);
                   w = x.parent.rightChild;
               }

               //case2


               if((w.rightChild.color.equals("black")) && (w.leftChild.color.equals("black"))){
                   System.out.println("2");
                   w.setColor("red");
                   counter2++;
                   x = x.parent;
               }

               //case 3
               else {
                   if(w.rightChild.color.equals("black")){
                       System.out.println("3");

                   w.leftChild.setColor("black");
                   counter2++;
                   w.setColor("red");
                   counter2++;
                   rightRotate(w, T);
                   w = x.parent.rightChild;

               }

               //case 4
                   System.out.println("4");
                        w.color = x.parent.color;
                        counter2++;
                        x.parent.setColor("black");
                        counter2++;
                        w.rightChild.setColor("black");
                        counter2++;
                        leftRotate(x.parent, T);
                        x = DUMMYROOT.leftChild;


               }
           }

           else{

               w = x.parent.leftChild;
               //case 1
               if(w.color.equals("red")){
                   System.out.println("5");
                   w.setColor("black");
                   counter2++;
                   x.parent.setColor("red");
                   counter2++;
                   rightRotate(x.parent, T);
                   w = x.parent.leftChild;
               }

               //case2

               if(w.rightChild.color.equals("black") && w.leftChild.color.equals("black")){
                   System.out.println("6");
                   w.setColor("red");
                   counter2++;
                   x = x.parent;
               }

               //case 3
               else {
                   if(w.leftChild.color.equals("black")){
                       System.out.println("7");
                   w.rightChild.setColor("black");
                   counter2++;
                   w.setColor("red");
                   counter2++;
                   leftRotate(w, T);
                   w = x.parent.leftChild;

                   }

               //case 4
               /**
               if(!(w.color == x.parent.color)){
                   w.color = x.parent.color;
                   counter2++;
               }
               **/ 

                   System.out.println("8");

                       w.color = x.parent.color;
                       counter2++;
                       x.parent.setColor("black");
                       counter2++;

                       w.leftChild.setColor("black"); //HERE THERES A NULL EXCEPTION
                       counter2++;             
                       rightRotate(x.parent, T);
                       x = DUMMYROOT.leftChild;

               }
           }
       }

       x.setColor("black");
       counter2++;
       return counter2;

    }

    private RBNode TreeSuccessor(RBNode node) {
        RBNode x = new RBNode();
        RBNode y = new RBNode();
        x=node;

        if (x.getRightChild()!=this.NULL) {
            return minNode(x.getRightChild());
        }
        y=x.getParent();
        while ((y!=this.NULL) && (x==y.getRightChild())) {
            x=y;
            y=x.getParent();
        }
        return y;
    }

       public RBNode minNode(RBNode startNode) {
           RBNode currNode= new RBNode();
           currNode=startNode;
           if (currNode==this.NULL) {
               System.out.println("currNode==this.NULL");
               return currNode;
           }
           else
           {
               while (currNode.leftChild!=this.NULL)
                   currNode=currNode.leftChild;
           }
           return currNode;
       }

   static class RBNode{

       public RBNode(int key) {
           this.key=key;
       }

        private double key;
        private RBNode parent;
        private RBNode rightChild;
        private RBNode leftChild;
        private String info;
        private String color;

       public RBNode() {

          this.key=-1;
          this.leftChild=null;
          this.rightChild=null;
          this.parent=null;
      }

      public RBNode(int key, String color) {
          this.color=color;
          this.key=key;
          this.leftChild=null;
          this.rightChild=null;
          this.parent=null;

      } 

      public RBNode(int key, String color, RBNode left, RBNode right) {
          this.color=color;
          this.key=key;
          this.leftChild=left;
          this.rightChild=right;

      } 

      public double getKey() {
          return this.key;
      }

      public String getColor() {
          return this.color;
      }  

      public RBNode getParent() {
          return this.parent;
      }     

      public RBNode getLeftChild() {
          return this.leftChild;
      }     

      public RBNode getRightChild() {
          return this.rightChild;
      } 

      public void setColor(String color) {
          this.color=color;
      }  

      public void setKey(double key) {
          this.key=key;
      }  

      public void setParent(RBNode parent) {
          this.parent=parent;
      }     

      public void setLeftChild(RBNode leftChild) {
          this.leftChild=leftChild;
      }     

      public void setRightChild(RBNode rightChild) {
          this.rightChild=rightChild;
      } 


}

   public static void main(String[] args) {

        RBTree t = new RBTree();

        t.insert(14);
        t.insert(11);
        t.insert(7);
        t.insert(8);
        t.delete(11);


    }
公共类RBTree{
私有RBNode DUMMYROOT;
私有节点空;
私有int节点;
公共关系树(){
this.numOfNodes=0;
this.NULL=新的RBNode();
this.DUMMYROOT=new RBNode();
this.DUMMYROOT.setKey(Double.POSITIVE_无穷大);
this.DUMMYROOT.setLeftChild(NULL);
这个.DUMMYROOT.setColor(“黑色”);
此.NULL.setColor(“黑色”);
}
公共RBNode getNULL(){
返回this.NULL;
}
/**
*公共布尔空()
* 
*当且仅当树为空时返回true
*  
*/
公共布尔空(){
if(this.numOfNodes==0)
返回true;
返回false;
}
/**
*公共布尔搜索(int i)
* 
*当且仅当树包含i时返回true
*  
*/
公共布尔搜索(双i){
return(递归搜索(i,this.DUMMYROOT.getLeftChild())!=NULL);
}
公共RBNode搜索节点(双i){
返回递归搜索(i,this.DUMMYROOT.getLeftChild());
}
专用RBNode递归搜索(双i,RBNode RBNode){
if(rbNode==NULL)
返回NULL;
else if(rbNode.getKey()==i)
返回rbNode;
else if(rbNode.getKey()k)
x=x.getLeftChild();
其他的
x=x.getRightChild();
}
返回y;
}
private int RBTreeInsert(RBTree t,RBNode z){
rby节点;
y=树位置(t.DUMMYROOT,z.getKey());
如果(z.getKey()!=y.getKey()){
z、 setParent(y);
z、 setLeftChild(NULL);
z、 setRightChild(空);
z、 设置颜色(“红色”);

如果在
w.leftChild.setColor(“黑色”)中出现NullPointerException,请添加用于启动整个过程的主方法
那么很可能
w
没有左子节点。我建议在调试器中运行该程序,并找出在哪些情况下,节点是在没有设置
leftChild
的情况下构造的。@trapo:我添加了main方法和deletion方法。@Frank van Puffelen:谢谢,你是对的,但我以前就意识到了这一点。我的问题是,让它开始解决这个问题的算法有什么错误。问题是w的值来自空节点(senital),根据定义,它没有子节点。请添加代码的所有相关部分,以便我可以使用调试器进行测试。