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?
java wyszukiwanie binarne drzewo
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).
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.
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.
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)
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));
}
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;
}













