标签:
查找就是在由若干记录组成的集合中找出关键字值与给定值相同的记录。如查找成功,返回找到的记录的信息或者在表中的位置,查找失败就返回一个代表失败的标志。一个查找算法的优劣取决于查找过程中的比较次数,使用平均比较长度(平均比较次数)ASL来衡量查找算法的效率,ASL是和指定值进行比较的关键字的个数的期望值。
ASL=∑n1Pi*Ci
其中,Ci表示查找到第i个数据元素时已经比较的次数,Pi是查找表中第i个数据元素的概率。
根据查找算法是否改变查找表的内容,将查找算法分为静态查找和动态查找。静态查找对查找表查找时,查找成功就返回记录的信息或在查找表中的位置,查找失败就返回一个代表失败的标志,并不对查找表进行插入和删除,或经过一段时间之后再对查找表进行集中式的插入和删除操作。动态查找是查找与插入和删除在同一阶段进行,例如,在某些问题中,查找成功时,删除查找到的记录,查找失败时,插入被查找的记录。
无序查找要求查找表有序无序均可。有序查找要求查找表必须是有序的。
顺序查找算法是最简单的查找算法,从查找表的一端开始,顺序查找每个记录,直至另一端为止。实现代码如下:
1 //顺序查找,n是数组长度,a从[0,n-1] 2 public static int sequenceSearch(int[] a,int value,int n){ 3 int i=0; 4 while (i<n&&a[i]!=value){//比较大小和检查边界同时进行 5 ++i; 6 } 7 if(i<n){ 8 return i;//查找成功 9 } 10 else { 11 return -1;//查找失败 12 } 13 }
查找成功时的平均查找长度是:
查找失败时平均查找长度是(无序表的查找,到最后一个元素才能确定查找失败):n。
为简化边界条件而引入的附加节点(记录)均可称为哨兵,哨兵常用在循环和递归中,用于边界条件的检查。上述顺序查找算法不仅要比较查询表中元素是否与查找值相同,同时还要检测是否越界,因此可以添加哨兵,简化程序,添加哨兵后的代码如下:
1 //添加哨兵的顺序查找,n是数组最后一个元素的索引,[1,n]是查找表内容,a[0]是哨兵 2 public static int sequenceSearch2(int[] a,int value,int n){ 3 int i=n; 4 a[0]=value; 5 while (a[i]!=value){//通过哨兵避免了边界检查 6 --i; 7 } 8 if(i>0){ 9 return i;//查找成功 10 } 11 else { 12 return -1;//查找失败 13 } 14 }
查找成功时的平均查找长度是仍然是(n+1)/2。查找失败时的平均查找长度是n+1(最后需要与哨兵比较,多了一次比较)。
在查找表元素个数大于1000时,添加哨兵的查找时间几乎减少了一半。顺序查找算法对查找表的存储结构没有要求,顺序存储和链式存储均可应用,并且对表中记录的顺序也没有要求,不过,查找效率低下,时间复杂度是O(n)。
标签:
原文地址:http://www.cnblogs.com/lz3018/p/5779595.html