0

I am new to programming in Java , I had written code for trie to store numbers as bits(the last 31 bits from right) . Therefore each node has only two possible children at max, 0 or 1.

The node for each trie node has the following attributes

  • Node next[] : array of size 2 pointing to next node
  • int visCnt : Number of times a node has been visited, this will be
    used to later delete the node ( check remove function below)
  • int number : the number stored at leaf node , for ex., if we insert 5 to trie, the leaf node will have value of 'number' as 5 meanwhile all other nodes from root till leaf will have default val of -1

The functions that i have implemented are

  • void insert(int num) : insert 'num' to global trie
  • void remove(int num, Node A,int ind) : recursive function to delete a number if it exists in global trie. For node A , I pass the root(of global trie) from the main, and reach the node to be delete. From the leaf, nodes are deleted bottom up , by checking value of visCnt.
  • boolean isExist(int num) : To check if num exists in global trie

The remove function in the implementation doesn't work as expected, I have pasted the code down below for reference, (you can try running on a site like onlineGDB where it will work fine). In the main function after i insert(4) and then remove(4) i expect isExist(4) to return false but this is not the case and it returns as true. Does setting the node object as null not delete the node ?

Code:

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;
    }
}

Ouput

added 1
added 2
added 4
removed 4
checking for  4
4 exists in trie 
95_96
  • 341
  • 2
  • 12

1 Answers1

2

I changed your remove() to this:

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;
    }
}

It is working...

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 

Added 4 twice.

Explanation:

Your problem was in here:

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

When you are putting null in the reference A, then the parent of A is not getting it. As Java is Call by value, not call by reference. So you need to do this:

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

And rest codes are to cope with the changes. I Hope, you got the reason.

Mukit09
  • 2,956
  • 3
  • 24
  • 44