一、顺序查找
顺序查找又称线性查找,主要用于在线性表中进行查找。
1.1 无序表的顺序查找
对无序线性表进行顺序查找,查找失败时要遍历整个线性表
int search_seq_u(int elems[], int key) {
int i;
for(i = elems.length-1; i >=0 && elems[i]!=key; i--);
return i;
}
同理,ASL失败 = n
1.2 有序表的顺序查找
对关键字有序线性表进行顺序查找,查找失败时不一定要遍历整个线性表
在此我们引入二叉排序树:
有n+1个失败节点,查找成功的ASL依旧为(n+1)/2
二、折半查找
折半查找又称二分查找,仅适用于有序的顺序表
算法思想:
首先将给定值key与表中中间位置元素的关键字比较,
若相等,则返回该元素的位置;
若不等,则在前半部分或者是后半部分进行查找.查找序列升序时,
若key小于中间元素,则查找前半部分;
若key大于中间元素,则查找后半部分。
重复该过程,直到找到查找的元素为止;或查找失败。
int binary_search(int sq[], int key) {
int low = 0, high = sq.length-1,mid;
while(low<=high) {
mid = (high+low) / 2;
if(sq[mid]==key)
return mid;
else if(sq[mid]>key)
high = mid-1;
else {
low = mid+1;
}
}
return -1;
}
折半查找判定树(更像平衡二叉树,查找效率更高):
上面这个例子的ASL成功为:(1×1+2×2+3×4+4×4)/11 = 3【每个结点的查找次数加以来除以节点数】
ASL失败为(3×4+4×8)/12 = 11/3
三、分块查找
分块查找又称索引顺序查找,它吸取了顺序查找和折半查找各自的优点,
既有动态结构,又适于快速查找。
如何分块:
将查找表分为若干子块。块内的元素可以无序,但块间是有序的,即对于所有块有第 i 块的最大关键字小于第 i+ 1块的所有记录的关键字。
建立索引表,索引表中的每个元素含有各块的最大关键字和各块中的第一个元素的地址,索引表按关键字有序排列。
如何查找
- 在索引表中确定待查记录所在的块,可以顺序查找或折半查找索引表。
- 在块内进行顺序查找