简体   繁体   中英

java: why this binarySearch with comparator is not working?

Updated: I am trying to use Collections.sort() to sort an arrayList with a comparator parameter. Then do binarysearch.

package collection;

import java.util.*;

public class TryBinarySearch {
    public static void main(String[] args){
        List<Integer> list = new ArrayList<>();
        for (int i = 0; i < 100; i++)
           list.add(i);
        System.out.println(list);
        int b = Collections.binarySearch(list, 8);
        System.out.println(b); // a is 8 as expected.

        Collections.shuffle(list);
        System.out.println(list);   

        Collections.sort(list, new
                Comparator<Integer>(){
            public int compare(Integer a, Integer b){
                return b.intValue() - a.intValue();
            }
        });
        System.out.println(list);   //list is reversed as expected.
        int a = Collections.binarySearch(list, 8);
        System.out.println(a); // why a is -1?
    }
}

b is 8 as expected; I made a reverse sorting. My question is why a is -1, instead of 92?

You shuffled the list, so it is not sorted. You must have a sorted list to do a binary search

To perform a binary search, the list must be sorted. You first shuffled the list, which invalidates the prerequisite of Collections.binarySearch .

The list must be sorted into ascending order according to the specified comparator (as by the sort(List, Comparator) method), prior to making this call. If it is not sorted, the results are undefined.

The algorithm relies on the list being sorted. So of course when you sort it later, binarySearch works.

Binary search only works when the list is already sorted. The way that binary search works is that the algorithm assumes that if the value at its "guess" index is higher than the one we're looking for, the actual index must be lower - and vice versa.

If the collection isn't sorted, that assumption doesn't hold, so the algorithm fails.

The documentation states this very clearly:

The list must be sorted into ascending order according to the specified comparator (as by the sort(List, Comparator) method), prior to making this call. If it is not sorted, the results are undefined.

Binary search depends on the list you are searching to be in order. You are explicitly shuffling yours. Do you mean to sort it via the Comparator instead?

When calling binarySearch(list, key) , the doc says:

The list must be sorted into ascending order according to the natural ordering

Your list is sorted using a custom Comparator , and therefore you need to pass it to the call to indicate the search algorithm how to compare item:

    Comparator<Integer> cmp = new Comparator<Integer>(){
        public int compare(Integer a, Integer b){
            return b.intValue() - a.intValue();
        }
    };
    Collections.sort(list, cmp);
    System.out.println(list);   //list is reversed as expected.
    int a = Collections.binarySearch(list, 8, cmp);

For this call, the doc says:

The list must be sorted into ascending order according to the specified comparator

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM