[英]Delete node in binary search tree
我已經實現了以下方法來刪除 BST 中的節點,以遵循 此處發布的示例:
NodeT類
public class NodeT {
int elem;
NodeT left;
NodeT right;
public NodeT(int elem){
this.elem=elem;
}
}
二叉樹類
public class BinaryTree {
NodoT root;
public void insertElem(int n){
root=addRec(root,n);
}
public NodoT addRec(NodeT n, int elem){
if (n==null){
n=new NodeT(elem);
}
else{
if (elem<n.elem){
n.left=addRec(n.left,elem);
}
else{
n.right=addRec(n.right,elem);
}
}
return n;
}
public void inorder(NodeT n){
if (n!=null){
inorder(n.left);
System.out.println(n.elem);
inorden(n.right);
}
}
public NodeT search(NodeT root, int n){
if (root.elem==n) return root;
else{
if (n<root.elem){
if (root.left!=null){
return search(root.left,n);
}
else return null;
}
else{
if (root.right!=null){
return search(root.right,n);
}
else return null;
}
}
}
public void delete(int n){
root=deleteNode(root,n);
}
public NodeT deleteNode(NodeT curr, int n){
NodoT answ;
answ=search(curr,n);
if (answ==null){
System.out.println("not found");
return curr;
}
else{
if (curr.left==null)return curr.right;
else if (curr.right==null) return curr.left;
curr.elem=minValue(curr.right);
curr.right=deleteNode(curr.right,curr.elem);
}
return curr;
}
int minValue(NodoT curr){
int min=curr.elem;
while (curr.left!=null){
menor=curr.left.elem;
curr=curr.left;
}
return min;
}
//main program
BinaryTree bt=new BinaryTree();
int data[]={50,30,70,20,40,60,80};
for (int i=0;i<data.length;i++){
bt.insertElem(data[i]);
}
bt.inorder(bt.root);
bt.delete(20);
bt.inorder(bt.root);
bt.delete(30);
bt.inorder(bt.root);
bt.delete(50);
bt.inorder(bt.root);
但是,當我測試時,它在bt.delete(50);
線上打印“not found” bt.delete(50);
, 我究竟做錯了什么?
代碼中有很多錯誤,我認為您是從您的語言轉換而來的,並且遺漏了一些變量名稱。 但是,我更正了名稱並測試了代碼。
問題:在您的deleteNode()
,您不會在樹中重復出現,即檢查 If element 小於或大於curr
的值。 您需要添加更多IF
檢查。
解決方案:用這個替換你的deleteNode()
。
public NodeT deleteNode(NodeT curr, int n){
NodeT answ;
answ=search(curr,n);
if (answ==null){
System.out.println("not found");
return curr;
}
// need to check whether value is small or greater
if (n < curr.elem)
curr.left = deleteNode(curr.left, n);
else if (n > curr.elem)
curr.right = deleteNode(curr.right, n);
// if value is same, means this is the node to be deleted
else{
if (curr.left==null)
return curr.right;
else if (curr.right==null)
return curr.left;
curr.elem=minValue(curr.right);
curr.right=deleteNode(curr.right,curr.elem);
}
return curr;
}
public void insertElem(int n){
root=addRec(root,n);
}
每次添加一些值時都會覆蓋root
,所以在第二次插入時你會忘記它的父級等等,你最終只會知道大約 80,因為這是你插入的最后一個元素和你覆蓋root
的最后一個值和。 root
應該只在它為null
初始化,比如
if (root == null) root=addRec(root,n);
public NodoT addRec(NodeT n, int elem){
if (n==null){
n=new NodeT(elem);
}
else{
if (elem<n.elem){
n.left=addRec(n.left,elem);
}
else{
n.right=addRec(n.right,elem);
}
}
return n;
}
始終為您n.left
或n.right
到返回的值addRec
,該遺址的結構。 調用addRec
是正確的,但如果相應的值為null
, n.left
應將其分配給n.left
或n.right
。
從我們目前的觀點來看,似乎不相關。
看起來挺好的。
看起來挺好的。
public NodeT deleteNode(NodeT curr, int n){
NodoT answ;
answ=search(curr,n);
if (answ==null){
System.out.println("not found");
return curr;
}
else{
if (curr.left==null)return curr.right;
else if (curr.right==null) return curr.left;
curr.elem=minValue(curr.right);
curr.right=deleteNode(curr.right,curr.elem);
}
return curr;
}
您不是在比較實際數字。 這個想法應該是,如果值高於當前節點的值,則將在右分支中搜索要刪除的項目,否則將在左分支中搜索。 如果您需要搜索的分支到達null
,則該項目不存在於樹中。 參見 Zain Arshad 的實現。 我會做類似的事情,但由於他已經實施了它,我參考並贊成它,
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.