0
点赞
收藏
分享

微信扫一扫

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

GhostInMatrix 2022-02-14 阅读 47
#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;
}

实验样例

 

 

 

举报

相关推荐

0 条评论