typedef int KeyType;
typedef struct
{
KeyType key; //关键字项
InfoType data; //其他数据项,类型为InfoType
}RecType; //查找元素的类型
顺序查找
int SeqSearch(RecType R[],int n,KeyType k)
{
int i=0;
R[n].key=k;
while(R[i].key!=k) //从表头往后找
{
i++;
}
if(i==n)
return 0;
else
return i+1;
}
ASL成功=(n+1)/2
ASL成功=n
平均时间复杂度:O(n)
.
折半查找
int Bin Search(RecType R[],int n,KeyType k)
{
int low=0,high=n-1,mid
while(low<=high)
{
mid=(low+high)/2;
if(R[mid].key==k)
return mid+1;
if(k<R[mid].k)
high=mid-1;
else
low=mid+1;
}
return 0;
}
成功的折半查找过程:一条从判定树的根
到被查结点
(内部结点)的路径
,经历比较的关键字次数恰好为该元素在树中的层次。
ASL成功=
∑
i
=
1
n
p
i
×
l
e
v
e
l
(
k
i
)
\displaystyle\sum_{i=1}^{n} p_i×level(k_i)
i=1∑npi×level(ki)
pi表示概率
level(ki)表示关键字ki对应内部结点的层次
失败的折半查找过程:一条从判定树的根
到某个外部结点
的路径
,所需的关键字比较次数是该路径上内部结点的总数。
ASL失败=
∑
i
=
1
n
q
i
×
l
e
v
e
l
(
u
i
−
1
)
\displaystyle\sum_{i=1}^{n} q_i×level(u_i-1)
i=1∑nqi×level(ui−1)
qi表示概率
level(ui)表示对应外部结点的层次
平均时间复杂度:O(log2n)
.
例题
分块查找
每一块中的关键字不一定是有序的,但前一块中的最大关键字必须小于后一块中的最小关键字。
索引表的数据类型说明如下:
#define MAXI<索引表的最大长度>
typedef int KeyType;
typedef struct
{
KeyType key; //关键字项
InfoType data; //其他数据项,类型为InfoType
}RecType; //查找元素的类型
typedef struct
{
KeyType key; //为关键字的类型
int lik; //指向对应块的起始下标
}IdxType; //索引表元素的类型
int IdxSearch(IdxType I[],int b,RecType R[],int n,KeyType k)//索引表 索引表长度 数据表 查找的元素
{
int s=(n+b-1)/b; //类似向上取整+1操作,s为每块中的元素个数
int low=0,high=b-1;mid,i;
while(low<=high)
{
mid=(low+high)/2;
if(I[mid].key>=k)
high=mid-1;
else
low=mid+1;
}
//应先在索引表的high+1块中查找,然后再主数据表中进行顺序查找
i=I[high+1].link;
while(i<=I[high+1].link+s-1&&R[i].key!=k)
i++;
if(i<=I[high+1].link+s-1)
return i+1; //查找成功,返回该元素的逻辑序号
else
return 0; //查找失败,返回0
}
⭐分块查找最少需要两次关键字比较
分块查找的基本思路:
①查找索引表索引表有序
,故可采用折半查找
或顺序查找
。
②然后在已确定的块中进行顺序查找因为块内元素无序
,只能顺序查找
。
例
解: