顺序查找(线性查找)
顺序查找(Sequential Search)又称为线性查找,是一种最简单的查找方法。
查找过程如下:
从线性表的一端开始顺序扫描线性表,依次将扫描到的结点关键字和给定值进行比较。
若当前扫描到的结点关键字与给定值相等,则查找成功;
若扫描结束后,仍未能找到关键字等于给定值的结点,则查找失败。
int Search_Seq(SSTable ST,KeyType key)
{ // 在顺序表ST中顺序查找其关键字等于key的数据元素。若找到,则函数值为
// 该元素在表中的位置,否则为0。算法9.1
int i;
ST.elem[0].key=key; // 哨兵
for(i=ST.length;!EQ(ST.elem[i].key,key);--i); // 从后往前找
return i; // 找不到时,i为0
}
有序表查找(折半查找【也叫二分查找】】)
当静态查找表为有序表示,那么可以使用折半查找算法来查找,
折半查找(Binary Search)的查找过程如下:
先确定待查记录所在的范围(区间),然后逐步缩小范围 知道找到或找不到该记录为止。
它对线性表的要求是:关键字值按递增或递减顺序排列。
首先,将要查找的关键字k与中间位置结点的关键字比较,中间结点把线性表分为了两个子表,
若比较结果相等,则查找结束。
若不相等,再根据关键字与该中间结点关键字的 比较结果确定下一步在哪个子表区间内查找。这样递归进行下去。
直到找到满足条件的结点或该线性表中没有这样的结点。
int Search_Bin(SSTable ST,KeyType key)
{ // 在有序表ST中折半查找其关键字等于key的数据元素。若找到,则函数值为
// 该元素在表中的位置,否则为0。算法9.2
int low,high,mid;
low=1; // 置区间初值
high=ST.length;
while(low<=high)
{
mid=(low+high)/2;
if EQ(key,ST.elem[mid].key) // 找到待查元素
return mid;
else if LT(key,ST.elem[mid].key)
high=mid-1; // 继续在前半区间进行查找
else
low=mid+1; // 继续在后半区间进行查找
}
return 0; // 顺序表中不存在待查元素
}
索引查找(分块查找)
索引顺序查找,又称分块查找。是顺序查找的一种改进。其性能介于顺序查找和折半查找之间。
分块查找把线性表分成若干块,每一块中的元素存储顺序是任意的,但是块与块之间必须是按关键字大小排序(即前一块中的最大关键字大于(或小于)后一块中的最小(或最大)关键字值)。
另外,需要建立一个索引表,索引表中的一项对应线性表中的一项,索引项由关键字域和链域组成,关键字域存放相应块的最大关键字,链域存放指向本块第一个结点的指针,链域存放指向本块第一个结点的指针,索引表按关键字值递增(或递减)顺序排列。
索引表查找算法:实际上进行了两次查找(折半查找+顺序查找)。因此整个算法的平均查找长度是两次查找的平均查找长度之和。
int Search_block(SSTable ST,KeyType key) /*自定义实现分块查找*/
{
int i, j;
for (i = 1; i <= N; i++)
{
index_table[i].start = j + 1; /*确定每个块范围的起始值*/
j = j + 1;
index_table[i].end = j + 4; /*确定每个块范围的结束值*/
j = j + 4;
index_table[i].key = a[j]; /*确定每个块范围中元素的最大值*/
}
i = 1;
while (i <= N && key > index_table[i].key) /*确定在那个块中*/
i++;
if (i > N) /*大于分得的块数,则返回0*/
return 0;
j = index_table[i].start; /*j等于块范围的起始值*/
while (j <= index_table[i].end && ST.elem[i] != key) /*在确定的块内进行查找*/
j++;
if (j > index_table[i].end) /*如果大于块范围的结束值,则说明没有要查找的数,j置0*/
j = 0;
return j;
}