7.2.1 顺序查找
1、应用范围:
- 顺序或线性链表表示的静态查找表
- 表内元素之间无序
2、数据元素类型定义:
typedef struct
{
KeyType key; //关键字域
...; //其它域
}ElemType;
typedef struct
{
ElemType R[MAXSIZE];
int length;
}SSTable;
3、在顺序表ST中查找值为key的数据元素,例如:
int Search_Seq(SSTable ST, KeyType key)
{
for (int i = ST.length; ST.R[i].key != key && i > 0; --i);
if (i > 0)
return i;
else
return 0;
}
这种方法没执行一次循环都要进行两次比较。
4、改进:把待查找关键字key存放入表头(“哨兵”,“监视哨”),从后往前逐个比较,可免去查找过程中每一步都要检测是否查找完毕,加快速度。
int Search_Seq(SSTable ST, KeyType key)
{
ST.R[0].key = key;
for (int i = ST.length; ST.R[i].key != key; --i);
return i;
}
5、时间效率分析:
比较次数与位置有关:查找第i个元素,需比较n-i+1次;查找失败,需比较n+1次。
6、顺序查找的性能分析:
时间复杂度:O(n)
查找成功的平均查找长度,设表中各记录查找概率相等;ASLs(n) = (1+2+...+n)/n = n+1/2
空间复杂度:一个辅助空间O(1)
7、记录的查找概率不相等时如何提高查找效率?
查找表存储记录原则——按查找概率高低存储
(1)查找概率越高,比较次数越少
(2)查找概率月底,比较次数越多
8、记录的查找概率无法测定时如何提高查找效率?
方法:按查找概率动态调整记录顺序
(1)在每一个记录中设一个访问频度域
(2)始终保持记录按非递增有序的次序排序
(3)每次查找后均将刚查到的记录一道表头
9、顺序查找的特点:
优点:算法简单,逻辑次序无要求,且不同存储结构均适用
缺点:ASL太长,时间效率太低
7.2.2 折半查找(二分查找或对分查找)
1、折半查找:每次将待查找记录所在区间缩小一半。
2、查找过程:
3、折半查找算法(非递归算法):
设表长为n,low、high和mid分别指向待查找元素所在区间的上界、下届和中点,key为给定的要查找的值。
(1)初始时令low = 1,high = n,mid = ;
(2)让key 与mid指向的记录比较:
若key = ST.R[mid].key,则查找成功;
若key < ST.R[mid].key,则high = mid - 1;
若key > ST.R[mid].key,则low = mid + 1.
(3)重复上述操作,直至low > high时,折半查找失败。
折半查找的非递归算法实现:
int Search_Bin(SSTable ST, KeyType key)
{
int low = 1, high = ST.length, int mid;
while (low < high)
{
mid = (low + high) / 2;
if (ST.R[mid].key == key)
return mid;
else if (ST.R[mid].key > key)
high = mid - 1;
else if (ST.R[mid].key < key)
low = mid + 1;
else
return 0;
}
}
折半查找的递归算法实现:
int Search_Bin(SSTable ST, KeyType key, int low, int high)
{
if (low > high)
return 0;
int mid = (low + high) / 2;
if (key == ST.R[mid].key)
return mid;
esle if (key < ST.R[mid].key)
return Search_Bin(ST, key, low, mid - 1);
else
return Search_Bin(ST, key, mid + 1, high);
}
4、折半查找的性能分析——判定树
比较次数 = 路径上的结点数 = 结点的层数
比较次数 <= 树的深度 <=
假设每个元素的查找概率相等,求查找成功时的平均查找长度:
ASL = (1*1 + 2*2 + 4*3 +4*4) / 11= 3
5、折半查找的特点:
优点:效率比顺序查找高
缺点:只适用于有序表,且限于顺寻存储结构(对线性链表无效)。
7.2.3 分块查找(索引顺序查找)
1、步骤:
(1)将表分成几块,且表或者有序,或者分块有序;若 i < j,则第 j 块中所有记录的关键字均大于第 i 块的最大关键字。
(2)建立“索引表”(每个结点含有最大关键字域和指向本块第一个结点的指针,且关键字有序)。
2、查找过程:先确定待查记录所在块(顺序或折半查找),再在块内查找(顺序查找)。
3、分块查找的优缺点
优点:插入和删除比较容易,无需进行大量移动
缺点:要增加一个索引表的存储空间,并对初始索引表进行排序运算
适用情况:如果线性表计要快速查找又经常动态变化,则采用分块查找。
7.2.4 三种查找的比较
顺序查找 | 折半查找 | 分块查找 | |
ASL | 最大 | 最小 | 中间 |
表结构 | 有序、无序 | 有序 | 分块有序 |
存储结构 | 顺序表、线性链表 | 顺序表 | 顺序表、线性链表 |