数据结构-静态查找表(分块查找)

该程序使用C++实现了一个查找表的索引创建和搜索功能。首先通过`Create_IdxTable`函数创建索引表,根据输入的查找表元素个数和索引块长度,采用分块并记录最大键值的方式构建索引。然后使用`Search_Idx`函数,通过索引表进行折半查找定位到目标块,并在块内进行顺序查找。程序在主函数中演示了整个流程,最后输出查找结果。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

#include <iostream>
using namespace std;

typedef int KeyType;
//定义查找表
typedef struct {
	KeyType key;
}ElemType;
typedef struct {
	ElemType* data;
	int length;
}SSTable;

//定义索引表与表内分块
typedef struct {
	KeyType key; //块内最大键值
	int stadr; //块起始地址
}indexItem;
typedef struct {
	indexItem* data; //索引表基地址
	int length; //索引表长度
}indexTable;

bool Create_IdxTable(SSTable& ST, indexTable& ID, int n, int t);//n代表查找表中元素个数,t代表每个索引块长度
int Search_Idx(SSTable ST, indexTable ID, KeyType kval);

bool Create_IdxTable(SSTable& ST, indexTable& ID, int n, int t){
	ST.data = new ElemType[n + 1];
	if (!ST.data) return 0;
	cout << "请输入查找表元素:" << endl;
	for (int i = 1; i <= n; i++)
		cin >> ST.data[i].key;
	ST.length = n;
	int count = n / t; //计算块数
	if (n % t != 0) count++;//将剩余数据单独放入一个块
	ID.data = new indexItem[count];//构造索引表共count个块
	if (!ST.data) return 0;
	for (int i = 0; i < count; i++) {//遍历每一个块
		int k;//用来记录每个块存储数据的实际长度
		ID.data[i].stadr = i * t + 1;//查找表中第一个位置为空,因此首地址增1
		if (ID.data[i].stadr + t < ST.length)//若未到达查找表末尾
			k = ID.data[i].stadr + t - 1;
		else//若已到达末尾,则长度就是查找表的长度
			k = ST.length;
		KeyType max = ST.data[ID.data[i].stadr].key;//设定初始的块内最大值
		for (int j = ID.data[i].stadr + 1; j <= k; j++)//找出实际块内最大值
			if (ST.data[j].key > max)
				max = ST.data[j].key;
		ID.data[i].key = max;
	}
	ID.length = count;
	return true;
}


int Search_Idx(SSTable ST, indexTable ID, KeyType kval){
	int low = 0, high = ID.length - 1;  int mid = (low + high) / 2;
	if (kval > ID.data[high].key) return 0; //kval大于所有关键字,查询结束
	while (low <= high) {//折半查找索引表,确定记录查找区间
		mid = (low + high) / 2;
		if (kval < ID.data[mid].key)  high = mid - 1;
		else if (kval > ID.data[mid].key)  low = mid + 1;
		else { low == mid; break; }
	}
	//下一步的查找范围定位在第mid块
	int stadr = ID.data[mid].stadr;  //没啥用,太长了懒得写不好看,找个变量代替一下,是查找区间的下界
	int top;//同理,查找区间的下界
	if (mid < ID.length - 1)//若不是最后一个块
		top = ID.data[mid + 1].stadr - 1;
	else top = ST.length;  //stard和top为在ST表进行查找的下界和上界
	if (ST.data[stadr].key == kval)  return stadr;
	else {  //在ST.data[stard] 至ST.data[top-1]的区间内进行顺序查找
		ST.data[0] = ST.data[stadr]; //暂存ST.data[top]
		ST.data[stadr].key = kval;   //确保只在本块中寻找
		int k;
		for (k = top; ST.data[k].key != kval; k--);//k==stadr时必然结束
		ST.data[stadr] = ST.data[0]; //恢复暂存值
		if (k != stadr) return k;  else return 0;
	}
}




int main()
{
	SSTable ST;
	indexTable ID;
	int n, i, t;
	KeyType key;
	cout << "请输入查找表中元素个数:" << endl;
	cin >> n;
	cout << "请输入索引块长度:" << endl;
	cin >> t;
	if (!Create_IdxTable(ST, ID, n, t)) {
		cout << "查找表赋值失败" << endl;
		return 1;
	}
	cout << "请输入要查找的元素关键字值:" << endl;
	cin >> key;
	i = Search_Idx(ST, ID, key);
	if (i == 0)
		cout << "未找到!" << endl;
	else
		cout << "找到,位序为" << i << endl;
	return 0;
}

实验样例

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

菜菜的大鹏

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值