Trie 删除函数的意外运行

Unexpected functioning of Trie delete function

我是 Java 中的编程新手,我编写了 trie 代码以将数字存储为位(从右起最后 31 位)。因此每个节点最多只有两个可能的子节点,0 或 1。

每个 trie 节点的节点具有以下属性

我实现的功能有

实现中的remove函数没有按预期工作,我把代码贴在下面供参考,(你可以在onlineGDB这样的网站上试试运行,它可以正常工作)。在我插入(4)然后删除(4)之后的主要功能中,我希望 isExist(4)为 return false 但事实并非如此,它 returns 为真。将节点对象设置为null不删除节点吗?

代码:

import java.util.*;
import java.lang.*;
import java.io.*;
public class Main
{
    static class Node{
        Node next[] = new Node[2];
        int visCnt=0;
        int number = -1;
    }
    static Node root = new Node();
    void insert(int num){
        System.out.println("added "+num);
        Node cur =root;
        for(int i = 30;i>=0;i--){
            cur.visCnt++;
            int tmp = 1<<i;
            int curBit = ((tmp&num)==0)?0:1;
            if(cur.next[curBit]==null)
                cur.next[curBit] = new Node();
            cur=cur.next[curBit];
        }
        cur.visCnt++;
        cur.number = num;
    }
    void remove(int num, Node A,int ind){
        if(A==null){
            System.out.println("removed "+num);
            return;
        }
        A.visCnt--;
        int curBit = ((1<<ind)&num)==0?0:1;
        remove(num,A.next[curBit],ind-1);
        if(A.visCnt==0){
            A=null;
        }
    }
    boolean isExist(int num){
        System.out.println("checking for  "+num);
        Node cur =root;
        for(int i = 30;i>=0;i--){
            cur.visCnt++;
            int tmp = 1<<i;
            int curBit = ((tmp&num)==0)?0:1;
            if(cur.next[curBit]==null){
                System.out.println(num+ " does not exist in trie ");
                return false;
            }
            cur=cur.next[curBit];
        }
        System.out.println(cur.number+ " exists in trie ");
        return true;
    }
    public static void main(String[] args) {
        Main trie = new Main();
        trie.root.visCnt++;
        trie.insert(1);
        trie.insert(2);
        trie.insert(4);
        trie.remove(4,root,30);
        trie.isExist(4);
        // return ans;
    }
}

输出

added 1
added 2
added 4
removed 4
checking for  4
4 exists in trie 

我将你的 remove() 更改为:

void remove(int num, Node A,int ind){
    A.visCnt--;
    if(A.next[0]==null && A.next[1] == null){
        System.out.println("removed " + num);
        return;
    }
    int curBit = ((1<<ind)&num)==0?0:1;
    remove(num,A.next[curBit],ind-1);
    if(A.next[curBit].visCnt == 0){
        A.next[curBit]=null;
    }
}

正在运行...

added 1
added 2
added 4
added 4
removed 4
checking for  4
4 exists in trie 
removed 4
checking for  4
4 does not exist in trie 

添加了 4 两次。

解释:

你的问题在这里:

if(A.visCnt==0){
    A=null;
}

当您将 null 放入引用 A 时,那么 A 的父级没有得到它。因为 Java 是 按值调用 ,而不是 按引用调用 。所以你需要这样做:

if(A.next[curBit].visCnt == 0){
    A.next[curBit]=null;
}

其余代码是为了应对变化。我希望,你明白原因了。