在查找过程中,查找长度是指需要比较的关键词次数,平均查找长度是指所有查找过程中进行关键字比较次数的平均值。平均查找长度是衡量查找效率的重要指标。
一、顺序查找
顺序查找是从线性表一端开始,逐个检查数据元素是否满足给定的条件,若满足,则查找成功,返回该元素在线性表当中的位置,若已经查到表的另一端仍未找到指定元素,则查找失败。位置0存放待查找元素,作为“哨兵”的作用。
(1)查找成功的平均查找长度
若表中有n个元素,若查找元素在第i个位置,则查找该元素需要比较n+1-i次。
由上述可知,查找成功的平均查找长度
ASL=
当Pi=1/n时,查找成功的平均查找长度
ASL=
(2)查找失败
每查找一个元素就需要在顺序表中比较n+1次。
即查找失败的平均查找长度
ASL=n+1
若为有序顺序表的顺序查找,可以用判定树来模拟查找过程。
树中圆形表示表中存在元素,即能够被查找到的元素;矩形表示表中不存在的元素,为失败结点(一个表中若有n个元素,则其失败结点对应地有n+1个)。一个元素若能够被查找成功,则查找长度为自身所在树中的层数;若查找失败,则查找长度为其父结点所在层数。
(1)查找成功的平均查找长度:与普通顺序查找的ASL相等。
(2)查找失败的平均查找长度
二、折半查找
- 先将key与查找表中间元素进行比较,若相等,则查找成功,返回存储位置;
- 若大于中间元素,则查找元素只有可能在后半部分,在表的后半部分重复步骤1;
- 若小于中间元素,则查找元素只有可能在前半部分,在表的前半部分重复步骤1;
- 重复上述步骤,直到找到为止,或确定表中没有待查找元素。
以下图为例,圆形为成功节点,矩形为失败结点。
(1)查找成功的平均查找长度
ASL=(1+2*2+3*4+4*4)/11=3
ASL=
=
(2)查找失败的平均长度(即层数*失败结点数/失败节点总数)
对应上图为ASL=(3*4+4*8)/12=11/3
三、分块查找
将查找元素表分为若干块,块内元素无序,块间有序。前一个块中的所有元素必须小于后一个块中所有元素,并为其建立索引表,索引表中每个元素包含每个块中的最大元素和第一个元素的地址。
索引表可以顺序查找和折半查找,块内需要顺序查找(因为无序)。
设索引查找的平均查找长度为L1,块内查找平均长度为L2。
(1)查找成功的平均查找长度
ASL=L1+L2
设查找表中有n个元素,将查找表均匀地分为b块,每块有s个记录(n=bs)。
若块内和索引表均采用顺序查找,则平均查找长度等于:
ASL==
当s=时,取最小平均查找长度+1。
四、二叉排序树
二叉排序树的查找思想与折半查找类似,而不同点如下
存储结构 | 能否动态插入结点 | 如何找到比较的结点 | |
折半查找 | 顺序表 | 不可以 | [查找长度/2] |
二叉排序树 | 二叉树 | 可以 | 二叉树的每一层结点 |
(1)查找成功的平均查找长度
二叉排序树的查找效率与树的高度有关,若二叉树的左右子树的高度差绝对值不超过1,即平衡二叉树,其查找时间复杂度为; 若二叉树只有单支,则查找时间复杂度为O(n)。
平均查找长度ASL=(层数*每层结点数)/n。
五、散列表查找
已知散列函数,可以求得散列表。
线性探测再散列法:
(1)查找成功的平均查找长度
查找成功时,在等概率情况下,查找每个表中元素的概率是相等的。因此,根据表中元素个数来计算平均查找长度,个关键字的比较次数与散列函数和冲突处理方式有关。例如,元素序列{7,8,30,11,18,9,14},散列函数为:H(key)=(key*3)mod7,则构造的散列表如下:
key | 7 | 8 | 30 | 11 | 18 | 9 | 14 |
H(key) | 0 | 3 | 6 | 5 | 5 | 6 | 0 |
采用线性探测再散列法处理冲突,所构造的散列表为
地址 | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 |
关键字 | 7 | 14 | 8 | 11 | 30 | 18 | 9 |
在查找成功时,在等概率情况下,查找每个表中元素的概率是相等的。因此,根据表中元素的个数来计算平均查找长度,各关键字比较次数即为查找元素带入散列函数计算,根据得到的结果去表中查找,直到成功为止。因此,各关键字比较次数如下所示:
key | 7 | 8 | 30 | 11 | 18 | 9 | 14 |
比较次数 | 1 | 1 | 1 | 1 | 3 | 3 | 2 |
因此查找成功ASL=(1+1+1+1+3+3+2)/7=12/7
(2)查找失败的平均长度
在查找失败情况下,在等概率情况下,经过散列函数计算后只可能映射到的位置与散列函数(mod后的数字有关)来计算平均查找长度,即若mod后的数字为7,则经散列函数计算后只可能映射到表中0-6位置。简而言之,每个位置查找失败的比较一直到该位置的下一个空位为止,若查找不到对应元素,即查找失败。
对于采用开放定址法建立的散列表不能随意删除数据,因为有可能导致因冲突而向后挪的数据被“截断”,可以先给删除数据的位置做一个标记,,当查找时遇到删除的标记时,即使当前位置为空,也仍需要向后查找一个
H(key) | 0 | 1 | 2 | 3 | 4 | 5 | 6 |
比较次数 | 3 | 2 | 1 | 2 | 1 | 5 | 4 |
则查找失败的查找长度为ASL=(3+2+1+2+1+5+4)/7=18/7
拉链法:
对于不同关键字可能会通过散列函数映射到同一个地址,,为了避免非同义词发生冲突,可以把所有同义词存储在一个线性链表中。
(1)查找成功的平均查找长度
查找成功时,其比较次数与链表层数有关。以上图为例,第一层有6个元素,第二层有4个元素,第三层有1个元素,第四层有1个元素。查找第几层元素对应地就需要比较几次,因此查找成功的平均查找长度为:
ASL=(1*6+2*4+3*1+4*1)/11
(2)查找失败的平均查找长度
查找失败时,对于地址0,比较1次之后确定元素不在表中(空指针算一次),查找长度为1;对于地址1,比较5次之后确定元素不在表中,以此类推,则查找失败的查找长度为:
ASL=(1+5+1+3+1+1+3+2+1+1+3+2+1)/13=25/13
散列表平均查找长度与散列函数、处理冲突的方法和装填因子有关,因此要想提高散列表查找效率,可以从这三方面入手。