【问题标题】:Unusual Java implementation of red/black tree node insertion红/黑树节点插入的异常Java实现
【发布时间】:2018-10-04 02:14:02
【问题描述】:

我正在用 Java 编写一个关于红/黑树的类程序。我对它们通常的工作方式有很好的了解,并且应该使用递归插入方法。我通常会使用以下内容,以匹配我教授的 Node 课程。关于颜色,a 0 是黑色,a 1 是红色。给我们的 Node 类根本不处理键。

private static void put(int val,  int col)
{ root = put(root, val, col); }

private static Node put(Node n, Integer val, int col)
{
    if (n == null){
        Node t=new Node(val);
        t.setColor(1);
        return t;
    }
    int cmp = val.compareTo(n.getValue());

    if (cmp < 0) n.setLeft(put(n.getLeft(), val, col));
    else if (cmp > 0) n.setRight(put(n.getRight(), val, col));
    else n.setColor(col);

    if (isRed(n.getRight()) && !isRed(n.getLeft())) n = rotateLeft(n);
    if (isRed(n.getLeft()) && isRed(n.getLeft().getLeft())) n = rotateRight(n);
    if (isRed(n.getLeft()) && isRed(n.getRight())) flipColors(n);
    return n;
}

然而,问题是我们应该返回一个布尔值——如果用户插入了一个已经在树上的重复值,我们返回 false 并且不附加节点。否则,我们附加它们并返回 true;为此提供给我们的代码如下,但不是递归的(项目要求的一部分)。虽然我还没有实现正确的平衡或旋转方式,但返回的布尔部分可以工作。

public boolean insertNode(Node node) {

    //Here is just an example of setting colors for a node. So far, it is in green color. But you need to modify the code to dynamically adjust the color to
    //either RED or BLACK according to the red-black logic 
    Node current_node;
    // if the root exists
    if (root == null) {
        root = node; // let the root point to the current node
        root.setColor(Node.BLACK);
        return true;
    } else {
        current_node = root;
        node.setColor(1);
        while (current_node != null) {
            int value = current_node.getValue();

            if (node.getValue() < value){ // go to the left sub-tree
                if (current_node.getLeft() != null) // if the left node is not empty
                    current_node = current_node.getLeft();
                else{ // put node as the left child of current_node
                    current_node.setLeft(node);
                    node.setParent(current_node);
                    current_node = null;    }   
                //System.out.println("Left:"+current_node); 
                }

            else if (node.getValue() > value){ // go to the right
                if (current_node.getRight() != null) // if the right node is not empty
                    current_node = current_node.getRight();
                else{ // put node as the right child of current_node
                    current_node.setRight(node);
                    node.setParent(current_node);
                    current_node = null;    }   
                //System.out.println("Right: "+current_node);   
                }

            else{
                //System.out.println("Else: "+current_node);
                return false;   }


            //if(current_node!=null&&current_node.getLeft()!=null&&current_node.getRight()!=null&&current_node.getLeft().isRed()&&current_node.getRight().isRed())
            //  flipColors(node);

        }
    }

    if(node.getParent()!=null){
        node=node.getParent();
        System.out.println("Case: node has parent, val="+node.getValue());
    }

    if(node.getLeft()!=null&&node.getRight()!=null){
        if((node.getRight().isRed())&&!node.getLeft().isRed())
            node=rotateLeft(node);
        if((node.getLeft().isRed())&&(node.getParent()!=null)&&(node.getParent().getLeft().getLeft()!=null)&&(node.getParent().getLeft().getLeft().isRed()))
            node=rotateRight(node);
        if((node.getLeft().isRed()) && (node.getRight().isRed()))
            flipColors(node);
    }
    return true;
}

我无法在网上找到任何类似的实现,似乎布尔值对于程序的 gui 正常工作是必要的。如果有人对从哪里开始有好的建议,我将不胜感激!

【问题讨论】:

    标签: java red-black-tree red-black-tree-insertion


    【解决方案1】:

    对于递归 insertNode,我建议您执行以下操作:创建一个函数 insertNode(Node node, Node current_node),它返回一个 boolean 值。这个想法是始终从根节点开始为当前调查的节点调用函数 insertNode。如果该节点不能立即添加到 current_node 中,则递归调用负责节点来处理该节点。我已经根据您的代码为您提供了一个简短的示例(一些 cmets 的基本思想是什么,显然缺少一些东西)。我希望,我正确地回答了您的问题,这有助于您理解。

    public boolean insertNode(Node node) {
        if (root == null) {
            root = node;
            root.setColor(Node.BLACK);
            return true;
        } else {
            boolean result = insertNode(node, root);
    
            if (result) {
                //Some other important stuff to do...
            }
    
            return result;
        }
    }
    
    public boolean insertNode(Node node, Node current_node) {
        int value = current_node.getValue();
    
        if (node.getValue() < value) {
            if (current_node.getLeft() != null) {
                // Investigate left
                return insertNode(node, current_node.getLeft());
            } else {
                // Insert node left
                return true;
            }
        } else if (node.getValue() > value) {
            if (current_node.getRight() != null) {
                // Investigate right
                return insertNode(node, current_node.getRight());
            } else {
                // Insert node right
                return true;
            }
        } else {
            return false;
        }
    }
    

    【讨论】:

      【解决方案2】:

      我现在有工作功能,如下:

      public boolean insertNode(Node node) {
          if(root==null){
              root=node;
              root.setColor(Node.BLACK);
              return true;
          }
          else
              node.setColor(Node.RED);
      
          return insertNode(node, root);
      
      }
      
      public boolean insertNode(Node node, Node cur){
      
          if(node.getValue()<cur.getValue()){
      
              if(cur.getLeft()!=null) 
                  return insertNode(node, cur.getLeft());
      
              else{
                  cur.setLeft(node);
                  node.setParent(cur);
                  handleInsertion(node);
                  return true;    }   }
      
          else if(node.getValue()>cur.getValue()){
      
              if(cur.getRight()!=null)
                  return insertNode(node, cur.getRight());
      
              else{
                  cur.setRight(node);
                  node.setParent(cur);
                  handleInsertion(node);
                  return true;    }   }
          else
              return false;
      }
      

      【讨论】:

        猜你喜欢
        • 2021-12-13
        • 1970-01-01
        • 2013-03-05
        • 2018-11-06
        • 2013-11-17
        • 2012-08-20
        • 1970-01-01
        相关资源
        最近更新 更多