Java бинарное дерево поиска

голоса
0

У меня есть вопрос о том, как бы я удалить ребенка из узла (корень)? Так как я не могу назвать удалить, если я ребенок нуль, дети будут этим ребенок двигаться вверх? Мол, я бы просто инициализировать его как нуль ?? Или я указываю на ребенка ребенка?

Задан 31/10/2009 в 20:40
источник пользователем
На других языках...                            


6 ответов

голоса
2

В традиционном двоичном дереве поиска, удаление узла может иметь различные последствия в зависимости от того, сколько детей у узла есть:

  • Узел без детей может быть просто удален
  • Узел с одним ребенком может быть удален, и узел будет заменен его единственным ребенком. Это правило применяется независимо от того, что ребенок является левым или правым потомком.
  • Узел с двумя детьми , имеет немного более сложное правило: вы должны найти преемник в заказе или упорядоченной предшественника узла необходимо удалить, заменить значение текущего узла с его sucessor или стоимостью предшественника, а затем удалить его правопреемник или предшественник ( в соответствии с этими правилами).
Ответил 31/10/2009 в 20:49
источник пользователем

голоса
0

Является ли это домашнее задание? Ничего плохого в том, что ... мы просто не хотели, чтобы помочь людям узнать, а не сказать им ответы.

Если вы просто установите дочерний узел обнулить вы потеряете какую-либо информацию о детях порожденных.

Ответил 31/10/2009 в 20:51
источник пользователем

голоса
0

Стандартный класс дерево будет знать своих детей, как правило, застревают в массиве или коллекции - в случае бинарного дерева, то есть только два прямых детей, поэтому размер массива фиксированной будет работать. Из-за того, что они, как правило, реализовать какой-то метод «removeMe», что ребенок называет, чтобы удалить из этого списка детей.

Как уже упоминалось выше, это становится сложнее, если ребенок, которого вы удаляете дети.

Ответил 31/10/2009 в 21:33
источник пользователем

голоса
0

Ответ Тима кажется, лучше. Но да, вы хотите, чтобы сделать один из трех вещей, в зависимости от того, какого ребенка это ваше удаление. Если вы ребенок пустым, дети ему не будет двигаться вверх, потому что вы потеряли ссылку на них. Вместо этого, вы хотите, чтобы определить, есть ли левые или правые дети ребенка ваши извлекая должны быть установлены на указатель, ссылающийся на ребенок вашего удаления. После того, как вы установили предыдущий узлы указатель (влево или вправо) для ребенка (влево или вправо) узла вашего удаления, вы обыкновение иметь ссылку больше на этот узел, так что нет никакой необходимости устанавливать его на нуль (вы можете» доступ т его больше. Если вы не писали какое-то двусвязный BST, в этом случае, что это не классический BST)

Ответил 01/11/2009 в 00:20
источник пользователем

голоса
0

Этот код должен помочь вам

public Node<T> getParentOf(Node<T> child){
    findParentOf(this.root, child);
    return temp;
}

private void findParentOf(Node<T> ROOT, Node<T> child){
    if(ROOT.hasLeft()){
        findParentOf(ROOT.left, child);
    }

    if(ROOT.left == child || root.right == child){
        temp = ROOT;
    }

    if(ROOT.hasRight()){
        findParentOf(ROOT.right, child);
    }
}


private void replaceNode(Node<T> original, Node<T> newNode){
    Node<T> tempParent = getParentOf(original);
    if(original == tempParent.left){
        tempParent.left = newNode;
    }else if(original == tempParent.right){
        tempParent.right = newNode;
    }
}

private void traverseChildrenAndAdd(Node<T> newParent, Node<T> oldParent){
    newParent.insert(oldParent.data);
    if(oldParent.hasLeft()){
        traverseChildrenAndAdd(newParent,oldParent.left);
    }



    if(oldParent.hasRight()){
        traverseChildrenAndAdd(newParent,oldParent.right);
    }
}
private void deleteNode(Node<T> ROOT, Node<T> d){
    if(d.data.compareTo(ROOT.data) < 0){
        deleteNode(ROOT.left, d);
    }else if(d.data.compareTo(ROOT.data) > 0){
        deleteNode(ROOT.right, d);
    }else if(d == this.root){
        if(this.root.hasLeft()){
            traverseChildrenAndAdd(root.left, root.right);
            root = root.left;
        }else if(root.hasRight()){
            root = root.right;
        }else{
            root = null;
        }
    }else{
        if(ROOT.hasLeft()&&ROOT.hasRight()){
            Node<T> successor = getMinNode(ROOT);
            replaceNode(successor, successor.right);
        }else if(ROOT.hasLeft() || ROOT.hasRight()){
            if(ROOT.hasLeft()){
                replaceNode(ROOT, ROOT.left);
            }else{
                replaceNode(ROOT, ROOT.right);
            }
        }else{
            replaceNode(ROOT, null);
        }
    }
}

public void remove(T data){
    deleteNode(this.root, new Node<T>(data));
}
Ответил 13/02/2011 в 10:14
источник пользователем

голоса
0

Вы можете сделать что-то вроде этого (псевдокод):

Учитывая корень дерева «корень» и узел для удаления или некоторые данные «х» сделайте следующее

 if x < root
      recurse to left child
 if x > root
      recurse to right child
 else //node found
      find the min item of the node right child //min item should be left most leaf node node
      replace the value of the node you want to delete with min nodes value
      now delete the min node
 return root;

код:

delete(Node root, Object x){
    if(root == null){
        return null;
    }

    if(data < root.data){
        root = delete(root.left);
    }else if(root.data < data){
        root = delete(root.right);
    }else{
        if(root.left != null && root.right != null){
            Object tmp = findMin(root.right);
            root.data = tmp;
            root.right = delete(root.right, tmp);
        }else{
            return (root.left != null) ? root.left : root.right;    
        }
    }
return root;

}

Ответил 09/09/2014 в 20:33
источник пользователем

Cookies help us deliver our services. By using our services, you agree to our use of cookies. Learn more