目录
1. 线性表的查找分类
- 顺序查找(线性查找)
- 折半查找(二分查找)
- 分块查找
2. 顺序查找
- 由数组或链表表示的静态查找表
- 表内元素是无序的
改进:哨兵
方法:表头留空,设置哨兵在a[0]处,从后往前查找。
效果:可以使for语句减少一半的比较次数(不需要判断if),最终减少算法约一半的运行时间:
注意:for后面要加分号,不然if就成了循环语句
时间效率分析
思考:如何减少比较次数,增加效率
1. 事先知道使用频率:将使用频率高的靠后存储(从后往前查找,哨兵在A[0])
2. 事先不知道使用频率:动态存储,给每个元素多设一个频度域,存储查找频度。将元素按使用频度递增存放,每次找到后将该元素放在表头。
优缺点
算法简单;逻辑次序无要求;
顺序存储结构与链式存储结构均适用。
ASL长,效率低。
3. 折半查找
如果查找表元素有序,(如字典)那么每次查找可以缩小一半的范围。
没找到则high在Low左边,结束条件。
思路(非递归)
非递归:伪代码
递归-伪代码
int Search(SSTable ST, Keytype key, int high, int low){
if(low > high) return 0;
mid = (high + low) / 2
if(key == ST.R[mid].key) return mid;
else if(key > ST.R[mid].key) Search(ST, key, high, mid+1);
else if(key < ST.R[mid].key) Search(ST, key, mid-1, low);
}
效率分析
使用判定树描述查找过程,可知树的深度即为最多比较次数。
有n个结点的树深度为 (向下取整)+ 1.
查找表中含11个元素,折半查找的ASL为3;而顺序查找,ASL则为6。可见提升约一半
PS: ASL = P(每个元素查找的概率) * c(需要的比较次数)
优缺点
效率比顺序查找高一倍左右。
需要有序。 PS:有序,意味着如果不是静态表,进行增删操作时,还需要移动大量的元素。
需要是数组(顺序存储结构),链表不适用。 (找不到mid)
4. 分块查找
分块查找:给查找表建立索引,可以根据索引知道目标在哪一部分。(如手机通讯录,字典a~z)
确定范围后,使用顺序查找。
分块查找是由两部分构成的,所以ASL也由两部分组成:
优缺点
效率比顺序查找高,和折半差距不会太大。
可以对查找表进行增删操作。
顺序存储结构与链式存储结构均适用。
需要分块有序。