javaarraylistbinary-searchnon-recursive

EDITED: Binary insertion not working as I think it should


Still newish to Java; our professor wants us to use a non-recursive binary search AT THE TIME OF ADDING elements to this ArrayList. I keep getting outofbounds exceptions, and I just can not find out why. I also notice unusual behavior while debugging and going step by step. For the life of me, I just can't seem to logically figure this out. He also wants us to use the compare method for this as well. My issue is figuring out why/how this keeps getting array out of bounds. Any pointers and advice will be greatly appreciated.....our professor is older and takes DAYS to get back via email, and I don't have that long to figure this problem out. This is the only thing holding me back for the rest of the assignment.

    public void enqueue(E item) {
    if(arr.size() == 0) {
        arr.add(item);
    }else {
        int low = 0;
        int high = (arr.size());
        while (low <= high){
            int mid = (low + high)>>1;
            if(arrComp.compare(arr.get(mid), item) < 0){
                low = (mid + 1);
            }
            else if (arrComp.compare(arr.get(mid), item) > 0){
                high = (mid - 1);
            }
            else{
                arr.add(mid,item);
            }
        }
    }
}   

***Edit When I do this:

int low = 0;
int high = (arr.size() - 1);
while (low <= high){
    int mid = (low + high) / 2;
    if(arrComp.compare(arr.get(mid), item) < 0){
        low = (mid + 1);
    }
    else if (arrComp.compare(arr.get(mid), item) > 0){
        high = (mid - 1);
    }
    else{
        arr.add(mid,item);
    }
}

}

Or this:

            if(arr.size() == 0){
                     arr.add(item)
}
            int low = 0;
            int high = (arr.size() - 1);
            while (low <= high){
                int mid = (low + high) / 2;
                if(arrComp.compare(arr.get(mid), item) < 0){
                    low = (mid + 1);
                }
                else if (arrComp.compare(arr.get(mid), item) > 0){
                    high = (mid - 1);
                }
                else{
                    arr.add(mid,item);
                }
            }

    }

Both get the method to run, neither actually fills the arraylist. I don't understand why this is not working, logically it should be filling the array should it not? It ran this time without error, but essentially did nothing. Array size is 0 and there are no elements after running, but at least it runs now.


Almost fully fixed my problem, but now a new issue cropped up that I can not figure out!!!!

        public void enqueue(E item) {
        int low = 0;
        int high = (arr.size());
        int mid =0;
        int cmp;
        if(arr.size()==0) {
            arr.add(item);
        }/**
        else if(arr.size()==1) {
            cmp = arrComp.compare(arr.get(0), item);
            if(cmp < 0){
                arr.add(item);
            }
            else {
                arr.add(0,item);
            }
        } **/
        else {
            while (low < high){
                mid = (low + high) / 2;
                cmp = arrComp.compare(arr.get(mid), item);
                if(cmp < 0){
                    low = (mid + 1);
                }
                else if (cmp > 0){
                    high = (mid - 1);
                }                   
            }
            arr.add(mid, item);
        }

}

My initialization for loop is elsewhere. As of right now, my output is {2, 3, 4, 5, 6, 1} using the above enqueue method as I initialize the arraylist. I can not for the life of me get this to fill it in order. GRANTED, my initialization is such that it is already in sequential order, but as per our assignment, we MUST initialize this using a binary search method when adding to the list.

WHY does the first initialized item stay at the end of the list? (the 1), when all other values get added in their correct location? Is it ONLY because the .add method of ArrayLists adds to the END of the list, even though it is the first value I am adding (using the .add method if the list size is currently 0)? How can I get around that?

My initial solution, the commented out part of the code, did nothing except make the output {3, 4, 5, 6, 1, 2} so I was even more confused, and I am now seeking advice.


Solution

  •  int high = (arr.size());// the why
    

    Perhaps you should update your code in these ways:

    1. high = arr.size() - 1;
    2. mid = low + (high - low) / 2; // otherwise when low and high is big (if size is big) it might overflow the integer;
    3. int cmp = arrComp.compare(arr.get(mid), item); // to avoid senseless comparison;