文章目录
查找(1)——概念和顺序表查找
介绍
本文为查找第一部分,主要是整理了本人上课时讲的内容,并给出了C语言代码的实现过程
查找的基本概念
名词术语
属性:描述一个客体某一方面特征的数据信息
记录:反映一个客体数据信息的集合
查找表:具有相同属性定义的记录的集合
关键字:区分不同记录的属性或属性组——主关键字/次关键字
主关键字(Primary Key):可以唯一的标识一个记录
查找表的逻辑结构(Search Table)
记录呈现在用户眼前的排列的先后次序关系
线性结构
查找表的物理结构
查找表(文件)在存储介质上的组织方式
- 连续组织方式(顺序组织方式)
- 链接组织方式
- 索引组织方式
- 随机组织方式(散列组织方式)
前两个是顺序查找,第三个是索引查找,第四个是散列查找
查找表的基本操作
查找、插入、删除、修改、排序
静态查找表和动态查找表
静态查找表
如果只在查找表中确定某个特定记录是否存在或检索某个特定记录的属性,此类查找表为静态查找表(Static Search Table)
动态查找表
如果在查找表中需要插入不存在的数据元素(记录)或需要删除检索到的数据元素(记录),此类查找表为动态查找表(Dynamic Search Table)
顺序表的查找
顺序表的基本概念
在物理结构中记录排列的先后次序与在逻辑结构中记录排列的先后次序一致的查找表称为顺序表
逻辑上划分
记录的排列按关键字值有序的顺序表称为有序顺序表,否则,称为一般顺序文件。
物理上划分
在存储介质上采用连续组织方式的顺序表称为连续顺序表;采用链接组织方式的顺序表称为链接顺序表
若排序顺序文件在存储介质上采用连续组织方式,称之为有序连续顺序表
顺序查找法
从表的第一个记录开始,将用户给出的关键字值与当前被查找记录的关键字值进行比较,若匹配,则查找成功,给出被查到的记录在表中的位置,查找结束。若所有n 个记录的关键字值都已比较,不存在与用户要查的关键字值匹配的记录,则查找失败,给出信息0。
平均查找长度
Average Search Length(ASL)—— 确定一个记录在查找表中的位置所需要进行的关键字值的比较次数的期望值(平均值)。
A
S
L
=
∑
i
=
1
n
p
i
c
i
ASL = \sum_{i = 1}^{n}{p_ic_i}
ASL=i=1∑npici
pi 为查找第 i 个记录的概率,ci 为查找第 i 个记录所进行过的关键字的比较次数。
对于具有n个记录的顺序表,若查找概率相等,则有
A
S
L
=
1
n
∑
i
=
1
n
i
=
n
+
1
2
ASL = \frac{1}{n}\sum_{i = 1}^{n}{i} = \frac{n+1}{2}
ASL=n1i=1∑ni=2n+1
折半查找(Binary Search)
对**有序**的查找表
将要查找的关键字值与当前查找范围内位置居中的记录的关键字的值进行比较。
若匹配,则查找成功,给出被查到记录在文件中的位置,查找结束。
若要查找的关键字值小于位置居中的记录的关键字值,则到当前查找范围的前半部分重复上述查找过程,否则,到当前查找范围的后半部分重复上述查找过程,直到查找成功或者失败。
若查找失败,则给出错误信息(0)。
非递归代码
int binSearch(int k[], int number, int key)
{
int low = 0, high = number - 1, mid;
while (low <= high)
{
mid = (low + high) / 2;
if (k[mid] == key)
{
return mid;
}
if (k[mid] > key)
{
high = mid - 1;
}
else
{
low = mid + 1;
}
}
return -1;
}
递归代码
int binSearch2(int k[], int low, int high, int key)
{
int mid = (low + high) / 2;
if (low > high)
{
return -1;
}
else
{
if (k[mid] == key)
{
return mid;
}
if (k[mid] > key)
{
binSearch2(k, low, mid - 1, key);
}
else
{
binSearch2(k, mid + 1, high, key);
}
}
}
判定树*
若把当前查找范围内居中的记录的作为根结点,前半部分与后半部分的记录的分别构成根结点的左子树与右子树,则由此得到一棵称为“判定树”的二叉树,利用它来描述折半查找的过程。
平均查找长度
A S L = 1 n ∑ i = 1 h j × 2 j − 1 = n + 1 n l o g 2 ( n + 1 ) − 1 ASL = \frac{1}{n}\sum_{i = 1}^{h}{j\times2^{j-1}} = \frac{n + 1}{n}log_2(n + 1) - 1 ASL=n1i=1∑hj×2j−1=nn+1log2(n+1)−1
此处是简化讨论做出的满二叉树,最大节点数为 n = 2 h − 1 n = 2^h-1 n=2h−1 ,则深度为 h = l o g 2 ( n + 1 ) h = log_2(n+1) h=log2(n+1) ,满二叉树中第 j j j 层的节点数为 2 j − 1 2^{j - 1} 2j−1
所以,可以得出时间复杂度为 O ( l o g 2 n ) O(log_2n) O(log2n)
适用范围:折半查找方法适用于一经建立就很少改动、而又经常需要查找的查找表。