符号表查找
以键值对进行存储,每个键对应一个不重复的值。
关键函数:put(key, value)、get(key)、delete(key)、contains(key)
常用的数据结构
一、链表
每个节点存储key、value、next;get的实现为遍历链表并找到相同的键;put的实现为遍历链表判断是否有相同的键,如果有则更新值,否则在链表头新增节点。
优点:适用于小问题
缺点:大型数据查找较慢
二、有序数组
使用一对平行数组,一个存储键一个存储值,保证键有序从而使用二分查找来实现get。这里引入一个rank函数,能够返回表中小于给定键的键的数量,这样get函数就能够通过rank返回对应键的下标,从而在值的数组中根据下标找到对应值;put函数能够使用rank找到存入的键所需放置的位置,再更新移动数组,将新的键值对插入。
//递归实现rank
int rank(int key, int lo, int hi){
if(hi < lo) return lo;
int mid = (lo + hi)/2;
if(key < a[mid])
return rank(key, lo, mid);
else if (key > a[mid])
return rank(key, mid, hi);
else
return mid;
}
//迭代实现rank
int rank(int key){
int lo = 0, hi = N-1;
while(lo <= hi){
int mid = (lo + hi)/2;
if (key < a[mid])
hi = mid -1;
else if (key > a[mid])
lo = mid +1;
else
return mid;
}
return lo;
}
int get(int key){
int i = rank(key);
if(i < N && keys[i] == key)
return vals[i];
else
return null;
}
void put(int key, int value){
int i = rank(key);
if(i < N && keys[i]==key){
vals[i] = value;
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++;
}
优点:最优的查找效率和空间需求;能够进行有序性相关操作
缺点:插入操作很慢
三、二叉树
结合了链表插入的灵活性和有序数组查找