一、算法思想
分块查找,又称索引顺序查找,是一种性能介于顺序查找和二分查找之间的查找方法

如上图,分块查找需额外引入 “索引表”,其结构定义如下:
typedef struct
{
int max_value; /* 块中最大值 */
int start_pos; /* 块的起始位置 */
int end_pos; /* 块的结束位置 */
} sub_block_t;
另外,还需保证第 i 个块中的最大值小于第 i+1 个块中的任一值
二、代码实现
#include <stdio.h>
#include <stdlib.h>
/* 定义块的索引结构 */
typedef struct {
int max_value; /* 块中的最大值 */
int start_index; /* 块在数组中的起始索引 */
int end_index; /* 块在数组中的结束索引 */
} BlockIndex;
/*
* 创建索引表
* 参数:
* arr - 要查找的数组
* length - 数组长度
* blockSize - 每个块的大小
* blockCount - 用于返回块的数量
* 返回值:
* 指向创建的索引表的指针
*/
BlockIndex* createIndex(int arr[], int length, int blockSize, int* blockCount) {
/* 计算块的数量 */
*blockCount = (length + blockSize - 1) / blockSize;
/* 分配索引表内存 */
BlockIndex* index = (BlockIndex*)malloc(*blockCount * sizeof(BlockIndex));
if (index == NULL) {
printf("内存分配失败\n");
exit(1);
}
/* 初始化索引表 */
for (int i = 0; i < *blockCount; i++) {
index[i].start_index = i * blockSize;
index[i].end_index = (i + 1) * blockSize - 1;
/* 最后一块可能超出数组长度,修正结束索引 */
if (index[i].end_index >= length) {
index[i].end_index = length - 1;
}
/* 找到当前块的最大值 */
index[i].max_value = arr[index[i].start_index];
for (int j = index[i].start_index + 1; j <= index[i].end_index; j++) {
if (arr[j] > index[i].max_value) {
index[i].max_value = arr[j];
}
}
}
return index;
}
/*
* 分块查找
* 参数:
* arr - 要查找的数组
* index - 索引表
* blockCount - 块的数量
* target - 要查找的目标值
* 返回值:
* 找到则返回目标值在数组中的索引,否则返回-1
*/
int blockSearch(int arr[], BlockIndex index[], int blockCount, int target) {
/* 1. 在索引表中查找目标可能所在的块 */
int blockIndex = -1;
for (int i = 0; i < blockCount; i++) {
if (target <= index[i].max_value) {
blockIndex = i;
break;
}
}
/* 如果没有找到合适的块,返回-1表示查找失败 */
if (blockIndex == -1) {
return -1;
}
/* 2. 在找到的块中顺序查找目标 */
for (int i = index[blockIndex].start_index; i <= index[blockIndex].end_index; i++) {
if (arr[i] == target) {
return i; /* 返回找到的位置索引 */
}
}
/* 在块中未找到目标 */
return -1;
}
int main()
{
int arr[] = {16, 5, 9, 12,
21, 18,
32, 23, 37, 26,
45, 34, 50, 48, 61, 52, 73, 66};
int length = sizeof(arr) / sizeof(arr[0]);
int blockSize = 6; /* 每个块的大小 */
int blockCount;
/* 创建索引表 */
BlockIndex* index = createIndex(arr, length, blockSize, &blockCount);
/* 打印索引表信息 */
printf("索引表信息:\n");
for (int i = 0; i < blockCount; i++) {
printf("块 %d: 起始索引=%d, 结束索引=%d, 最大值=%d\n",
i, index[i].start_index, index[i].end_index, index[i].max_value);
}
/* 测试查找 */
int targets[] = {12, 37, 50, 99};
int targetCount = sizeof(targets) / sizeof(targets[0]);
for (int i = 0; i < targetCount; i++) {
int result = blockSearch(arr, index, blockCount, targets[i]);
if (result != -1) {
printf("找到 %d,位置索引为 %d\n", targets[i], result);
} else {
printf("未找到 %d\n", targets[i]);
}
}
/* 释放内存 */
free(index);
return 0;
}
756

被折叠的 条评论
为什么被折叠?



