Mám otázku, jak bych odebrat dítě z uzlu (root)? Vzhledem k tomu nemohu volat odstranit, když udělám dětskou null, budou děti z tohoto dítěte pohybovat nahoru? Stejně jako bych právě inicializovat jako null ?? Jinak bych poukázat na dítě dítěte?
java binární vyhledávací strom
V tradičním binárního vyhledávacího stromu, odstranění uzlu může mít různé důsledky v závislosti na tom, kolik dětí má uzel:
- Uzel s žádnými dětmi lze jednoduše odstranit
- Uzel s jedním dítětem může být odstraněn, a uzel bude nahrazen jeho jediné dítě. To platí bez ohledu na to, zda je dítě levé nebo pravé dítě.
- Uzel se dvěma dětmi má poněkud složitější pravidlo: musíte najít nástupce v objednávku nebo in-pořadí předchůdce uzlu, které mají být odstraněny, nahradí hodnotu aktuálního uzlu s jeho sucessor je nebo hodnotě předchůdce, pak odstraňte nástupce nebo předchůdce (podle těchto pravidel).
Je to domácí úkol? Na tom není nic špatného ... jsme prostě chtěli pomoci lidem učit, spíše než říci jim odpovědi.
Pokud jste právě nastavit podřízený uzel na null ztratíte veškeré informace o Childs dětí.
Standardní třída strom bude znát své děti, obvykle uvízl v matici nebo kolekce - v případě binárního stromu, máte jen dvě přímé děti, tak fixní velikosti pole budou fungovat. Kvůli tomu, že obvykle realizovat nějaký způsob „removeMe“, že dítě volá, aby se z tohoto seznamu vyňaty dětí.
Jak již bylo uvedeno výše, toto komplikuje, pokud je dítě, o které má odebrání dětí.
Tim Odpověď se zdá nejlepší. Ale ano, budete chtít udělat jednu ze tří věcí, v závislosti na tom, jaké dítě je vaše odstranění. Pokud se stane, dítě null, budou děti něm nepohybují, protože jste ztratili odkaz na ně. Místo toho budete chtít zjistit, zda doleva nebo doprava, děti dítěte vaše odstranění by měla být nastavena na ukazovatel, ukazující na dítě svého odstranění. Po nastavení předchozí uzly ukazatel (vlevo nebo vpravo) k dítěti (vlevo nebo vpravo) uzlu svého odstranění, jste zvyklý mít referenci už do tohoto uzlu, tak theres není třeba nastavit tak, aby null (můžete‘ t mu přístup už ne. Pokud napsal nějaký dvojnásobně vázaného BST, v tom případě, že to není klasický BST)
Tento kód by vám měl pomoci
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));
}
Můžete udělat něco takového (pseudo kód):
Vzhledem k tomu, kořen stromu „root“ a uzel smazat nebo některá data „x“ proveďte následující kroky
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;
kód:
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;
}













