数据结构与算法(9)——索引查找

索引查找

索引的基本思想与字典类似,比如英文字典会提供一个目录,例如这样:A(01),B(13)…。这样能迅速定位到某个单词开头字母对应的页数以及开头字母结束的页数,迅速缩小了检索范围。使用索引查找,需要先构建索引表,分以下三步进行:

  1. 把表中的数据的关键字分成若干块:R1,R2,…,RL,这些块要满足Rk所有关键字小于Rk+1,k=1,2,3…,L-1,称为“分块有序”。
  2. 对每块建立一个索引项,成员包括关键字项(块中最大关键字的值),指针项(块的第一个记录在表中的位置),结构如下。
typedef struct IndexType
{
	KeyType key;
	int Link;
}IndexType;
  1. 所有索引项组成索引表。

索引查找分两步进行:

  1. 查找目录,定位元素所在的索引块。
  2. 将该数据块调入内存,查找数据。

索引表的顺序查找算法

注意,若将索引表分为m块,需要在索引数组的m+1位置传入一个key为空的索引项,作为第m块元素的停止位。

#include<stdio.h>
#include<stdlib.h>

typedef int KeyType;

typedef struct DataType
{
	KeyType key;
}DataType;

typedef struct IndexType
{
	KeyType key;
	int Link;
}IndexType;

int IndexSearch(IndexType* ls, DataType* s, int m, KeyType key)
{
	int i = 0;
	int j;

	while (i < m && key > ls[i].key)
	{
		i++;
	}
	if (i == m)
	{
		return -1;
	}
	j = ls[i].Link;
	while (key != s[j].key&& j < ls[i + 1].Link)
	{
		j++;
	}
	if (key == s[j].key)
	{
		return j;
	}
	else
	{
		return -1;
	}
}

//s必须满足前一个块的元素比后一个块的元素小
IndexType* GetIndexTable(DataType* s, int n, int m)
{
	IndexType* ls = (IndexType*)malloc(sizeof(IndexType) * (m+1)); //预留一个停止位
	int block_len = n / m;

	for (int i = 0; i < m; i++)
	{
		KeyType max = 0;
		for (int j = i * block_len; j < block_len * (i + 1); j++)
		{
			if (s[j].key > max)
			{
				max = s[j].key;
			}
		}
		ls[i].key = max;
		ls[i].Link = i * block_len;
	}
	ls[m].key = -1;
	ls[m].Link = n;

	return ls;
}

int main()
{
	DataType s[] = { 10,50,40, 60,55,53,70,80,90 };
	IndexType* ls = GetIndexTable(s, 9, 3);
	int j;


	j = IndexSearch(ls, s, 3, 80);
	printf("%d\n", j);
	free(ls);

	return 0;
}

性能分析

若索引块和索引块之间都采用顺序查找,则平均查找长度为索引块内部和索引块之间的平均查找长度之和,有:

在这里插入图片描述n为表长,b为数据块数目。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值