线性表查找
在查找表的组织方式中,线性表是最简单的一种。我们在学习线性表的时候对线性表操作的实现中就涉及到查找操作的实现,只不过当时没有考虑到效率或者其他的问题,只采用了最简单的一次循环遍历进行查找。
顺序查找(Sequential Search)
顺序查找(Sequential Search)的查找过程为:从表的一端开始,依次将记录的关键字和给定值进行比较,若某个记录的关键字和给定值相等,则查找成功;若在扫描整个表后仍未找到关键字和给定值相等的记录则表示查找失败。
顺序查找方法既适用于线性表的顺序存储结构,也适用于线性表的链式存储结构。
对于顺序存储结构查找成功时可以返回其在顺序表中的位置,对于链式存储结构在查找成功时则可以返回该元素的指针,即结点所在地址。
假设有一个学生结构体定义如下:
[C代码]
typedef struct _student
{
int stu_number; // 学号
char name[20]; // 姓名
char gender[4]; // 性别
// 其他信息略
}STUENDT;
typedef int KEY_TYPE; // 关键字类型,此处以学生的学号作为查询关键字
学生学号唯一,因此可以将学号作为主关键字来区分学生。
下面以在一个学生信息集合中根据主关键字学号来查找某个学生为例,分别从顺序存储结构和链式存储结构介绍顺序查找算法的实现。
顺序表的定义
顺序表查找
从查找表的一端开始依次比较,实现代码如下:
int seq_search(SSTABLE st, KEY_TYPE key)
{
int i;
for (i = 0; i < st.length; i++)
{
if (st.data[i].stu_number == key)
{
return i + 1; // 下标从0开始,返回的位置从1开始
}
}
return 0; // 返回0表示查找失败
}
这里使用主关键字进行查找,所以结果要么是找到唯一的一个,要么没有找到,包括后面的查找算法实现均讨论使用主关键字进行查找。
顺序存储结构的顺序查找实现的改进
前面的查找算法在每一次循环时都需要检测i是否越界,即判断i是否小于顺序表长度,可以改进这个程序来免去这个检测,具体的操作是:在顺序表存储数据元素时,从数组的下标1开始存储,下标0的元素空置,然后在实现顺序查找时,将下标0的元素赋值为查找给定的值,然后从后向前查找,由于下标0的元素现在也是和给定值相等,所以这次查找必然会找到结果:原顺序表中存在主关键字与给定值相等的记录或者在原顺序表中没有查找到结果而与下标0完成比较。
改进后算法实现如下:
int seq_search2(SSTABLE st, KEY_TYPE key)
{
st.data[0].stu_number = key;
int i = st.length;
while (st.data[i].stu_number != key)
{
i--;
}
return i;
}
测试完整源码: