二分查找

以二分法来提升查找效率

    private int rank(Key key) {
        if (key == null)
            throw new IllegalArgumentException("key can't be null");
        int lo = 0, hi = n - 1;
        while (lo <= hi) {
            int mid = lo + (hi - lo) / 2;
            int cmp = key.compareTo(keys[mid]);
            if (cmp < 0) {
                hi = mid - 1;
            } else if (cmp > 0) {
                lo = mid + 1;
            } else {
                return mid;
            }
        }
        return lo;
    }

二分法查找到key的合适位置

put

    public void put(Key key, Value value) {
        if (key == null)
            throw new IllegalArgumentException("key can't be null");
        if (value == null) {
            delete(key);
            return;
        }

        int i = rank(key);
        //这里要添加个i < n 判断,因为返回的i在没查找到的情况下可能等于n
        if(i < n && keys[i].compareTo(key) == 0){
            values[i] = value;
            return;
        }
        //扩容
        if (n == keys.length) {
            reSize(2 * keys.length);
        }
        //后挪空出i位
        for (int j = n; j > i; j--) {
            keys[j] = keys[j - 1];
            values[j] = values[j - 1];
        }
        keys[i] = key;
        values[i] = value;
        n++;
    }

get

    public Value get(Key key) {
        if (key == null)
            throw new IllegalArgumentException("key can't be null");
        if (isEmpty())
            return null;
        int i = rank(key);
        //为什么要判断i == n? key值大于所有情况下i为n,该情况不能进行compareTo判断
        if (i == n || keys[i].compareTo(key) != 0)
            return null;
        return values[i];
    }

delete

    public void delete(Key key) {
        if (key == null)
            throw new IllegalArgumentException("key can't be null");
        if (isEmpty())
            return;
        int i = rank(key);
        if (i == n || keys[i].compareTo(key) != 0)
            return;
        for (int j = n - 1; j > i; j--) {
            keys[j - 1] = keys[j];
            values[j - 1] = values[j];
        }
        n--;
        keys[n] = null;
        values[n] = null;

        if (n > 0 && n == keys.length / 4)
            reSize(keys.length / 2);
    }

二分查找的查找操作为O(logn),而插入操作在最坏情况下为2N,插入操作很慢

你可能感兴趣的:(二分查找)