簡體   English   中英

刪除二叉搜索樹中的節點

[英]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.leftn.right到返回的值addRec ,該遺址的結構。 調用addRec是正確的,但如果相應的值為nulln.left應將其分配給n.leftn.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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM