查找
文章目录
概述
-
查找 :在具有相同类型的记录构成的集合中找出满足给定条件的记录。
-
查找的结果 :若在查找集合中找到了与给定值相匹配的记录,则称查找成功;否则,称查找失败。
-
关键码:可以标识一个记录的某个数据项。
-
键值:关键码的值。
-
主关键码:可以唯一地标识一个记录的关键码。
-
次关键码:不能唯一地标识一个记录的关键码。
-
静态查找:不涉及插入和删除操作的查找 。(在查找过程中不进行插入删除等操作)
-
动态查找:涉及插入和删除操作的查找。 (涉及插入和删除操作)
-
查找结构 :面向查找操作的数据结构 ,即查找基于的数据结构。
-
线性表:适用于静态查找,主要采用顺序查找技术、折半查找技术。
-
树表:适用于动态查找,主要采用二叉排序树的查找技术。
-
散列表:静态查找和动态查找均适用,主要采用散列技术。
-
平均查找长度:将查找算法进行的关键码的比较次数的数学期望值定义为平均查找长度。或者说是自1到n求和
查找第 i 个记录的概率*查找第 i 个记录所需的关键码的比较次数
线性表查找
顺序查找
int SeqSearch1(int r[ ], int n, int k){
// 数组r[1] ~ r[n]存放查找集合
int i=n;
while (i>0 && r[i]!=k)
i--;
return i;
}
改进后的顺序查找
int SeqSearch2(int r[ ], int n, int k) {
//数组r[1] ~ r[n]存放查找集合
r[0]=k; // 即让0号元素一定会被查到,从而避免了判断是否越界
i=n;
while (r[i]!=k)
i --;
return i;
}
在计算ASL的时候,有个奇葩的规定(之后待考证),就是假设成功失败的可能都是1/2
优点
- 使用面广,算法简单
- 对存储没有任何要求,顺序和链式均可
- 对记录有序性也无要求,无论记录是否按照关键码有序
缺点
- 平均查找长度大,查找效率低
折半查找
条件
- 线性表中的记录必须按关键码有序
- 必须采用顺序存储
基本思想
在有序表中,取中间记录作为比较对象,若给定值与中间记录的关键码相等,则查找成功;若给定值小于中间记录的关键码,则在中间记录的左半区继续查找;若给定值大于中间记录的关键码,则在中间记录的右半区继续查找。不断重复上述过程,直到查找成功,或所查找的区域无记录,查找失败。
实现
// 非递归实现
int BinSearch1(int r[ ], int n, int k){
//数组r[1] ~ r[n]存放查找集合
low=1;
high=n;
while (low<=high) {
// 此处一定要记住终止条件
mid=(low+high)/2;
if (k<r[mid]) high=mid-1;
else if (k>r[mid]) low=mid+1;
else return mid;
}
return 0; // 其实是失败了
}
// 递归实现
int BinSearch2(int r[ ], int low, int high, int k){
//数组r[1] ~ r[n]存放查找集合
if (low>high) return 0; // 终止条件
else {
mid=(low+high)/2;
if (k<r[mid]) // 其实就是将前文的赋值改成了递归
return BinSearch2(r, low, mid-1, k);
else if (k>r[mid])
return BinSearch2(r, mid+1, high, k);
else return mid;
}
}
折半查找判定树
定义
折半查找的过程可以用二叉树来描述,树中的每个结点对应有序表中的一个记录,结点的值为该记录在表中的位置。通常称这个描述折半查找过程的二叉树为折半查找判定树,简称判定树。
构造
-
当n=0时,折半查找判定树为空;
-
当n>0时,折半查找判定树的根结点是有序表中序号为
mid=(n+1)/2
的记录,根结点的左子树是与有序表r[1] ~ r[mid-1]
相对应的折半查找判定树,根结点的右子树是与r[mid+1] ~ r[n]
相对应的折半查找判定树。
性能分析
- 具有n个结点的折半查找判定树的深度为 [log2n]+1 ([]表示向下取整)(n个节点的判定树和n个节点的完全二叉树深度相同)
- 查找成功:在表中查找任一记录的过程,即是折半查找判定树中从根结点到该记录结点的路径,和给定值的比较次数等于该记录结点在树中的层数。
- 查找不成功:查找失败的过程就是走了一条从根结点到外部结点的路径,和给定值进行的关键码的比较次数等于该路径上内部结点的个数,即使是失败了,其关键字比较个数最多也不会超过 [log2n]+1 ([]表示向下取整)
A S L = n + 1 n l o g 2 ( n + 1 ) − 1 ASL = \frac{n+1}{n}log_2(n+1)-1 ASL=n