java wyszukiwanie binarne drzewo

głosy
0

Mam pytanie w jaki sposób mogę usunąć dziecko z węzła (root)? Ponieważ nie mogę zadzwonić do usunięcia, jeśli robię null dzieci, będą dzieci tego dziecka poruszać się w górę? Podobnie jak, chciałbym tylko zainicjować go jako zerową ?? Albo chciałbym wskazać na dziecko dziecka?

Utwórz 31/10/2009 o 20:40
źródło użytkownik
W innych językach...                            


6 odpowiedzi

głosy
2

W tradycyjnym binarne drzewo poszukiwań, usunięcie węzła może mieć różne konsekwencje w zależności od tego, ile dzieci węzeł posiada:

  • Węzeł bez dzieci mogą być w prosty sposób usunięte
  • Węzeł z jednym dzieckiem może zostać usunięta, a węzeł zostanie zastąpiony przez swojego jedynego dziecka. Dotyczy to niezależnie od tego, czy dziecko jest w lewo lub w prawo dziecka.
  • Węzeł z dwójką dzieci ma nieco bardziej skomplikowaną regułę: musi znaleźć następcę na zamówienie lub poprzednik zamówienie węzła zostać usunięty, wymień wartość bieżącego węzła z jej sucessor użytkownika lub wartości poprzednika, a następnie usunąć następcy lub poprzednika (zgodnie z tymi zasadami).
Odpowiedział 31/10/2009 o 20:49
źródło użytkownik

głosy
0

Jest to praca domowa? Nic w tym złego, że ... po prostu lubię pomagać ludziom uczyć zamiast powiedzieć im odpowiedzi.

Jeśli po prostu ustawić węzeł podrzędny null stracisz żadnych informacji o Childs dzieci.

Odpowiedział 31/10/2009 o 20:51
źródło użytkownik

głosy
0

Standardowa klasa drzewo będą wiedzieć swoje dzieci, zwykle tkwi w tablicy lub Collection - w przypadku binarnego drzewa, masz tylko dwa bezpośrednie dzieci, a więc stałe wielkości tablica będzie działać. Z tego powodu, że zwykle realizować jakąś „removeMe” metody, która wywołuje dziecko, aby usunąć z tej listy od dzieci.

Jak wspomniano powyżej, to komplikuje, jeśli dziecko usuwasz ma dzieci.

Odpowiedział 31/10/2009 o 21:33
źródło użytkownik

głosy
0

odpowiedź Tima wydaje się najlepiej. Ale tak będzie chciał zrobić jedną z trzech rzeczy w zależności od tego, jakie dziecko to jest twój usuwanie. Jeśli się dzieckiem null, dzieci go nie ruszy, bo straciłeś odniesienie do nich. Zamiast tego, będziemy chcieli, aby ustalić, czy w lewo lub prawo dzieci dziecka swój usuwania powinien być ustawiony na wskazując kursorem dziecku swoje usuwania. Po ustawieniu poprzedniego węzłów wskaźnika (lewy lub prawy) do dziecka (lewy lub prawy) węzła swój usuwania, przyzwyczajenie się odniesienie już do tego węzła, więc tam nie trzeba go ustawiać na null (można” t dostęp go już. Chyba, że ​​napisał jakąś podwójnie połączonej BST, w tym przypadku nie jest to klasyczny BST)

Odpowiedział 01/11/2009 o 00:20
źródło użytkownik

głosy
0

Kod ten powinien pomóc

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));
}
Odpowiedział 13/02/2011 o 10:14
źródło użytkownik

głosy
0

Można zrobić coś tak (pseudo kod):

Biorąc pod uwagę korzeniem drzewa „root” a węzłem usunąć niektóre dane lub „x” należy wykonać następujące czynności

 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;

kod:

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;

}

Odpowiedział 09/09/2014 o 20:33
źródło użytkownik

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