查找的概念
查找(或检索)是在给定信息集上寻找特定信息元素的过程。
待查找的数据单位(或数据元素)称为记录。记录由若干数据项(或属性)组成,如学生记录:
其中,“学号”、“姓名”、“性别”、“年龄”等都是记录的数据项。若某个数据项的值能标识(或识别)一个或一组记录,称其为关键字(key)。若一个key能唯一标识一个记录,称此key为主key。如“学号”的值给定就唯一对应一个学生,不可能多个学生的学号相同,故“学号”在学生记录里可作为主key。若一个key能标识一组记录,称此key为次key。如“年龄”值为20时,可能有若干同学的年龄为20岁,故“年龄”可作次key。下面主要讨论对主key的查找。
查找定义及方法
查找的定义:
设记录表L=(R1 R2……Rn),其中Ri(l≤i≤n)为记录,对给定的某个值k,在表L中确定key=k的记录的过程,称为查找。若表L中存在一个记录Ri的key=k,记为Ri.key=k,则查找成功,返回该记录在表L中的序号i(或Ri 的地址),否则(查找失败)返回0(或空地址Null) 。
查找的方法:
查找方法很多,有顺序查找、折半查找、分块查找、树表查找及Hash表查找等等。查找算法的优劣将影响到计算机的使用效率,应根据应用场合选择相应的查找算法。
顺序表查找算法分析
所谓顺序表(Sequential Table),是将表中记录(R1 R2……Rn)按其序号存储于一维数组空间。其特点是相邻记录的物理位置也是相邻的。
记录Ri的类型描述如下:
typedef struct
{
keytype key; //记录key//
…… //记录其他项//
}Retype;
顺序表查找算法实现
顺序表查找特点:
可以对无序记录表查找,但是效率是最低的,查找某记录几乎要扫描整个表,当表长n很大时,会令人无法忍受。
平均查找长度: ASL=O(n)。
int SearchFun(int a[], int n, int x) //顺序查找函数
{
int i, f = -1;
for (i = 0; i < n; i++)
{
if (x = = a[i]) //查找到
{
f = i;
break; //退出
}
}
return f;
}
折半查找算法分析
当记录的key按关系≤或≥有序时,则对给定值k,逐步确定待查记录所在区间,每次将搜索空间减少一半(折半),直到查找成功或失败为止。
算法思想:
设两个指针(或游标)low、high,分别指向当前待查找表的上界(表头)和下界(表尾)。对于表(R1 R2……Rn),初始时low=0、high=n-1,令:mid=指向当前待查找表中间的那个记录。下面举例说明折半查找的过程。
折半查找特点:
只能对有序记录表查找,效率相对较高。
平均查找长度: ASL=O(log2(n+1)),大大优于O(n)。
int SearchFun(int a[], int n, int x) //折半查找
{
int mid, low, high;
low = 0;
high = n - 1;
while (low <= high)
{
mid = (low + high) / 2;
if (a[mid] = = x) //查找到
return mid; //返回
else if (a[mid] > x)
high = mid - 1;//如果x<mid位置记录的key,则让high=mid-1;
else
low = mid + 1;//如果x>mid位置记录的key,则让low=mid+1;
}
return -1; //未查找到
}