以二分法来提升查找效率
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,插入操作很慢