首先,必须强调一下,这还是我在数据结构专栏写的第一篇博客,之前虽然写了机器学习的博客,但都不怎么样,所以希望这篇博客能够比较优质吧...
检索算法效率的衡量
衡量检索算法效率的标准是平均查找长度(Average Search Length,ASL)也就是为确定某一个结点在数据集合中的位置,给定值与集合中的结点关键字所需进行的比较次数
线性表的检索
1.顺序检索
顺序检索是一种最简单的查找方法,基本思想是从表的一端开始,顺序(逐个)扫描线性表,依次将扫描到的结点关键字和给定值得Key进行比较,若相匹配则检索成功,若检索一遍之后依旧没有相匹配的值,则检索失败。
检索从后往前不断将待查找元素Key和当前元素比较,我们从后往前,每一次将当前元素与待查找元素进行比较前都需要判断是否已经查找完成 即(K>=0),我们可以在线性表的最前面设置一个与待查找关键字等值的数据元素,作为监视查找是否完成的“哨兵",这样再循环查找过程中就不需要每次判断是否查找完成。
基于链表的顺序检索算法从链表的第一个结点开始向前往后查找,成功则放回数据所在的地址,查找失败则返回NULL
顺序查找优点是简单到不能再简单,但缺点是查找时间长
顺序查找成功是的平均查找长度为:
对于每次关键字的查找,因为是从后往前查找嘛,所以第i个元素被查找的次数为n-i,利用等差数列的求和公式可以推出结果为(n+1)/2
查找失败时,算法的平均查找长度为:
对于每次关键字的查找,都需要遍历完整个顺序表才能完成,所以都是n次,概率为1/n,最终为n
有的时候表中各个记录的查找概率并不相等,若能事先知道每个结点的检索概率,并按照检索概率升序排列(如果从前往后检索,则为降序排列)线性表中的结点,则ASl可以取得极小值,按照以上思路我们可以在每个结点中附设一个访问频度域,并不断动态排序,所以这种最好采用链式表的存储方式
二分法检索:
二分检所又称为折半查找,,要求线性表按关键字从小到大或者从大到小排序。以下为二分检索法的非递归与递归实现算法:
int binsearch(seqlist l,int key)//非递归
{
int low = 0,high =l.len-1,mid;
while(low<=high)
{
mid=(low+high)/2;
if(l.data[mid]==key) return mid;
if(l.data[mid]>key) high=mid-1;
else low=mid+1;
}
return -1;
}
int binsearch2(sqlist l,int key ,int low,int high)#递归
{
int mid,k;
if(low>high)
return -1;
if(l.data[mid]==key)
return mid;
if(l.data[mid]>key)
return binsearch2(l,key,low,mid-1);
else
return binsearch2(l,key,mid-1,high);
}
设,线性表之多被平分k次即可完成查找。也就是最坏
次即可结束。
又因为通过一次查找找到的结点有1()个,两次有(
)个,一次类推,二分检索的平均查找次数为:
最后算出来为
二分查找一般只适用于静态查找表
分块检索:
分块检索又称为索引顺序查找,它是顺序检索法与二分检索法的一种结合,基本思想是:
首先把线性表分为若干块,在每一块中,结点的关键码不一定有序,但块和块之间必须是分块有序的,为了实现分块检索,我们还需要建立一个索引表,将每一块的最大的关键码值按块顺序存放在一个索引顺序表中。
查找时,首先在索引表中采用二分检索或顺序检索法确定待检索对象可能所在块的起始地址,然后在所在块内按顺序查找的方式去查找

由于分块检索的块内元素是无序的,所以在动态的分块检索表中,数据的增添、删除都比较用以实现。
本文探讨了检索算法的效率衡量标准——平均查找长度(ASL),并详细介绍了顺序查找、二分查找以及分块检索三种算法。顺序查找简单但效率较低,平均查找长度在成功和失败时有所不同。二分查找适用于已排序的线性表,平均查找长度更优。分块检索结合了顺序和二分查找的优点,适用于动态查找表。文章还讨论了如何通过优化检索概率来提升检索效率。

2489

被折叠的 条评论
为什么被折叠?



