基于有序数组的二分查找实现符号表
本文参考《算法(第4版)》
基于有序数组的二分查找实现符号表
键和值设计
符号表设计时需要考虑键的唯一性。
package algorithms.search;
class KeyTest implements Comparable<KeyTest>{
private int item;
KeyTest(int item){
this.item = item;
}
public int compareTo(KeyTest key) {
//return this.compareTo(item);
if(this.item == key.item)
return 0;
else if(this.item > key.item)
return 1;
else
return -1;
}
//保证键的唯一性
@Override
public boolean equals(Object obj){
return obj instanceof KeyTest && (this.item==((KeyTest)obj).item);
}
@Override
public int hashCode(){
return this.item;
}
public int getKey(){
return this.item;
}
public String toString(){
return "KeyTest#" + this.item;
}
public static void main(String[] args){
KeyTest keyTest1 = new KeyTest(5);
KeyTest keyTest2 = new KeyTest(5);
KeyTest keyTest1_ref = keyTest1;
System.out.println(keyTest1.hashCode());
System.out.println(keyTest2.hashCode());
System.out.println(keyTest1.equals(keyTest2));//true
System.out.println(keyTest1==keyTest2);//false 不是同一个对象;
System.out.println(keyTest1==keyTest1_ref);//true
int a = 5;
int b = 5;
System.out.print("a==b?: ");//true
System.out.println(a==b);//true
String s1 = new String("abcd");
String s2 = new String("abcd");
String s3 = "abcd";
String s4 = "abcd";
System.out.print("s1==s2?: ");//true
System.out.println(s1==s2);//true
System.out.println("s1.equals(s2): ");//true
System.out.print("s3==s4?: ");//true
System.out.println(s3==s4);//true
}
}
基于有序数组的二分查找实现符号表实现
package algorithms.search;
/**
* 基于有序数组的二分查找实现符号表
* */
//Key, Value为泛型参数
public class BinarySearchST<Key extends Comparable<Key>, Value> {
private Key[] keys;
private Value[] vals;
private int N;
BinarySearchST(int capacity){
keys = (Key[])new Comparable[capacity];
vals = (Value[])new Object[capacity];
this.N = 0;
}
public int size(){
return N;
}
public boolean isFull(){
return N == keys.length;
}
public boolean isEmpty(){
return N == 0;
}
public void put(Key key, Value val){
int i = rank(key);
if(i < N && key.compareTo(keys[i])==0){
vals[i] = val;
return; //跳出函数,不再往下执行;
}
for(int j = N; j > i; j--){
keys[j] = keys[j-1];
vals[j] = vals[j-1];
}
keys[i] = key;
vals[i] = val;
N++;
}
public Value get(Key key){
if(isEmpty()) return null;
int i = rank(key);
if(i < N && key.compareTo(keys[i])==0)
return vals[i];
return null;
}
public Key min(){
return keys[0];
}
public Key max(){
return keys[N-1];
}
//选择排名为k的键;
public Key select(int k){
if( k < N && k >= 0)
return keys[k];
else return null;
}
//大于等于key的最小值
public Key ceiling(Key key){
int i = rank(key);
if( i == N ) return null;
return keys[i];
//or
// if( i < N) return keys[i];
// else return null;
}
//小于等于key的最大值
public Key floor(Key key){
int i = rank(key);
if(i < N && key.compareTo(keys[i])==0)
return keys[i];
return keys[i-1];
}
public boolean contains(Key key){
int i = rank(key);
if( i < N && key.compareTo(keys[i]) == 0)
return true;
return false;
}
//rank()方法返回小于键的键的数量,lo的取值范围为[0,N];
//大于中间值,小的索引往右移;小于中间值,大的索引往左移动
public int rank(Key key){
int lo = 0;
int 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;
}
public String printKeys(){
return keys.toString();
}
public static void main(String[] args) {
BinarySearchST<KeyTest , ValueTest> bst = new BinarySearchST<KeyTest, ValueTest>(50);
for(int i = 0; i < 10; i++)
bst.put(new KeyTest(i), new ValueTest(i*2));
System.out.println(bst.N);
System.out.println(bst.printKeys());
System.out.println(bst.select(3).getKey());
System.out.println(bst.contains(new KeyTest(3)));
System.out.println(bst.get(new KeyTest(4)).getVal());
for(int i = 0; i < bst.N; i++)
System.out.print(bst.get(new KeyTest(i)).getVal() + " ");
}
}