索引表的顺序查找

索引表的顺序查找

基本策略

  • 采用建立“目录”的形式,先查找目录,然后根据目录将需要的数据块读入内存,从而实现只需先对小部分数据进行查询,提高查找效率的效果

索引表的建立

  1. 将线索表中数据按关键字分为若干块(块可按升序、降序排序)
  2. 对每块建立索引项,每一个索引项均包含:
    1. 关键字项(该块的最大、最小关键字)
    2. 指针项(记录该块第一个数据在线索表中的位置)
  3. 将所有索引项组成索引表

索引表的查找

  1. 查找目录 (根据索引表的关键字项查找记录所在块;根据指针项确定所在块的第一个记录的物理地址)
  2. 查找数据(在块内部根据关键字查找记录的详细信息)

实例分析

在这里插入图片描述

算法分析

以查找关键字为 38的数据为例:

  • 在索引表中查询,定位关键字为38的数据元素在索引表的第二块中
  • 从线索表的第七个数据开始遍历,直到索引表第二块遍历结束(>12)
  • 如果没有找到,则查找失败,否则,查找成功

算法实现(c语言)

  • 定义索引项、索引表

    #define BLOCK_NUMBER 3
    
    /*
    * Struct: IndexNode
    * Description: 索引表的索引项
    * Member: 
    *			data: 该块中最大关键字
    *			link: 该块第一个记录在表中的位置
    */
    typedef struct IndexNode
    {
    	int data;	//数据
    	int link;	//指针
    }IndexNode;
    
    //索引表
    IndexNode indextable[BLOCK_NUMBER];
    
  • 建立索引表

    #define BLOCK_NUMBER 3
    #define BLOCK_LENGTH 6
    
    /*
    * Function: IndexTable
    * Description: 建立索引表
    * Parameter: 
    			int s[]: 线索表
    			int l: 线索表长度
    			IndexNode indextable[]: 索引表数组
    * Return: void
    */
    void IndexTable(int s[], int l, IndexNode indextable[])
    {
    	int j = 0;
    	for (int i = 0; i < BLOCK_NUMBER; i++)
    	{
    		indextable[i].data = s[j];
    		indextable[i].link = j;
    		for (j; j < indextable[i].link + BLOCK_LENGTH && j < l; j++)
    		{
    			if (s[j] > indextable[i].data)
    			{
    				indextable[i].data = s[j];
    			}
    		}
    	}
    	for (int i = 0; i < BLOCK_NUMBER; i++)
    	{
    		indextable[i].link++;	
    	}
    }
    
  • 线索表的顺序查找

    #define BLOCK_NUMBER 3
    
    /*
    * Function: IndexSequelSearch
    * Description: 顺序表线索查找
    * Parameter: 
    *			int s[]: 线索表
    *			int l: 线索表长度
    *			IndexNode it[]: 索引表
    *			int key: 待查找关键字
    * Return: int
    *			-1: 查找失败
    *			>= 1: 关键字在线索表中的位置
    */
    int IndexSequlSearch(int s[], int l, IndexNode it[], int key)
    {
    	//块间查找
    	int i = 0;
    	while (key > it[i].data && i < BLOCK_NUMBER)
    	{
    		i++;
    		
    	}
    	if (i > BLOCK_NUMBER)
    	{
    		return -1;
    	}
    	else
    	{
    		//在块间顺序查找
    		int j = it[i].link - 1;	//6
    		while (key != s[j] && j < l) 
    		{
    			j++;
    		}
    		if (key == s[j])
    		{
    			return j + 1;
    		}
    		else
    		{
    			return -1;
    		}
    	}
    }
    

性能分析

在这里插入图片描述

算法测试(c语言)

#include <stdio.h>

#define BLOCK_NUMBER 3
#define BLOCK_LENGTH 6

/*
* Struct: IndexNode
* Description: 索引表的索引项
* Member: 
*			data: 该块中最大关键字
*			link: 该块第一个记录在表中的位置
*/
typedef struct IndexNode
{
	int data;	//数据
	int link;	//指针
}IndexNode;

//索引表
IndexNode indextable[BLOCK_NUMBER];

/*
* Function: IndexSequelSearch
* Description: 顺序表线索查找
* Parameter: 
*			int s[]: 线索表
*			int l: 线索表长度
*			IndexNode it[]: 索引表
*			int key: 待查找关键字
* Return: int
*			-1: 查找失败
*			>= 1: 关键字在线索表中的位置
*/
int IndexSequlSearch(int s[], int l, IndexNode it[], int key)
{
	//块间查找
	int i = 0;
	while (key > it[i].data && i < BLOCK_NUMBER)
	{
		i++;
		
	}
	if (i > BLOCK_NUMBER)
	{
		return -1;
	}
	else
	{
		//在块间顺序查找
		int j = it[i].link - 1;	//6
		while (key != s[j] && j < l) 
		{
			j++;
		}
		if (key == s[j])
		{
			return j + 1;
		}
		else
		{
			return -1;
		}
	}
}

/*
* Function: IndexTable
* Description: 建立索引表
* Parameter: 
			int s[]: 线索表
			int l: 线索表长度
			IndexNode indextable[]: 索引表数组
* Return: void
*/
void IndexTable(int s[], int l, IndexNode indextable[])
{
	int j = 0;
	for (int i = 0; i < BLOCK_NUMBER; i++)
	{
		indextable[i].data = s[j];
		indextable[i].link = j;
		for (j; j < indextable[i].link + BLOCK_LENGTH && j < l; j++)
		{
			if (s[j] > indextable[i].data)
			{
				indextable[i].data = s[j];
			}
		}
	}
	for (int i = 0; i < BLOCK_NUMBER; i++)
	{
		indextable[i].link++;
	}
}

/*
* Function: print
* Description: 打印查找的数据元素以及其在线索表中的位置
* Parameter: 
			int searchNumber 查找的数据元素
			int index		 IndexSequelSearch函数的返回值
* Return: void
*/
void print(int searchNumber, int index)
{
	if (index == -1)
	{
		printf("查找元素:%d\n", searchNumber);
		printf("查找失败!\n");
		printf("------------------------------\n");
		return;
	}
	else
	{
		printf("查找元素:%d\n", searchNumber);
		printf("元素位置:%d\n", index);
		printf("------------------------------\n");
		return;
	}
}

int main()
{
	int s[18] = {22, 12, 13, 8,   9, 20,
				 33, 42, 44, 38, 24, 48,
				 60, 58, 74, 49, 86, 53};

	IndexTable(s, 18, indextable);

	printf("线索表:");
	for (int i = 0; i < 18; i++)
	{
		printf("%d ",s[i]);
	}
	printf("\n");
	printf("------------------------------\n");

	int indexNumber1 = 38;
	int index1 = IndexSequlSearch(s, 18, indextable, indexNumber1);
	print(indexNumber1, index1);

	int indexNumber2 = 28;
	int index2 = IndexSequlSearch(s, 18, indextable, indexNumber2);
	print(indexNumber2, index2);

	return 0;
}

输出如下
在这里插入图片描述

参考资料

  1. 《数据结构与算法》北京大学出版社 2018年版 林劼 刘震 陈端兵 戴波 著
  • 1
    点赞
  • 22
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值