菜鸡笔记之——分块查找+注释练习
分块查找:
前提:整个线性表可以无序,但要求分块有序,比如由一组数据:
1,3,2,6,9,8,13,15,19,32
数据整体无序,但如果将其分为四组(1,3,2),(6,9,8),(13,15,19),(32),就能保证前一块的最大值比后一块中的任意一个值小,
这称为分块有序,每一组叫做一个“块”,而每一块的最大值记为key,用key来当作查找块的索引,因此分块查找也叫做索引查找,分块查找要求分块有序使其有较大的局限性。
思路:根据块的key值检索待查找的数在哪一块中(顺序查找或二分查找),然后在这个块里顺序查找目标值。
代码实现(分块查找1.0):
# include <stdio.h>
# include <stdlib.h>
typedef struct indextable
{
int key;
int num[5];
int addr;
}index;
int main(void)
{
int array[20] = {1,4,7,3,5, 8,11,13,10,14, 15,19,18,17,20, 25,24,27,30,32};
void find_key(index *,int *,int len,int block_num);
index index_table[4];
find_key(index_table,array,20,4);
/*copy the number of the array in the index_table*/
for (int i = 0;i<4;i++)
{
index_table[i].addr = 5*i;
for(int j = 0;j<5;j++)
{
index_table[i].num[j] = array[5*i+j];
}
}
/*search the target according to the index table*/
int indexsearch(index *,int,int,int);
int target,result;
printf("enter the number you want to search:");
scanf("%d",&target);
result = indexsearch(index_table,4,5,target);
/*print the search result on the screen*/
if (result==-1)
{
printf("can not find this number!\n");
}
else
{
printf("%d is the %dth number\n",target,result+1);
}
return 0;
}
/*
**function:find_key
**description:finding the largest number in every block and reserve it into index_table[i].key
**parameter 1:the name of the index_table
**parameter 2:the name of the array
**parameter 3:the length of the array
**parameter 4:the number of the blocks
*/
void find_key(index * index_table,int * array,int len,int block_num)
{
int i,j;
for (i = 0;i<block_num;i++)
{
index_table[i].key = array[5*i];
for(j = 1;j<5;j++)
{
if (array[5*i+j]>index_table[i].key)
{
index_table[i].key = array[5*i+j];
}
}
}
}
/*
**function:indexsearch
**description:finding the target in the array according to the index table
**parameter 1:the name of the index table
**parameter 2:the number of the blocks
**parameter 3:the length of each block
**parameter 4:the number that you want to find
**return:return subscriptindex of the number if find the target,or return -1
*/
int indexsearch(index * index_table,int block_num,int block_len,int target)
{
int i,j;
for (i = 0;i<block_num;i++)
{
if (target<=index_table[i].key)
{
break;
}
}
if (i==block_num)
{
return (-1);
}
for (j = 0;j<block_len;j++)
{
if (index_table[i].num[j]==target)
{
return (index_table[i].addr+j);
}
}
return -1;
}
运行结果:
以上代码的缺陷比较大:
1、无法控制数组的长度和实时输入数据;
2、无法控制块的长度;
3、要求数组的长度为块的长度的整数倍,当数组长度无法被块长度整除时会 出现问题;
针对以上问题重新写代码
代码实现(分块查找2.0)
# include <stdio.h>
# include <stdlib.h>
# include <math.h>
# define N 100
typedef struct indexblock
{
int key;
int number[N];
int addr;
}index;
int main(void)
{
void find_key(index *,int *,int,int,int);
void distribute(index *,int *,int,int,int);
int index_search(index *,int,int,int,int);
int array_len,block_len;
printf("please enter the length of the array:");
scanf("%d",&array_len);
int * array = NULL;
array = (int *)malloc(sizeof(int)*array_len);
if (array==NULL)
{
printf("error!\n");
exit(-1);
}
/*enter the number*/
printf("please input %d numbers in specific sequence:\n",array_len);
for (int i = 0;i<array_len;i++)
{
scanf("%d",array+i);
}
printf("the length of each block:");
scanf("%d",&block_len);
/*finding the key of each block*/
int block_num = ceil((float)array_len/(float)block_len); /*upward rounding*/
printf("block_num :%d\n",block_num);
index index_table[block_num];
find_key(index_table,array,array_len,block_num,block_len);
/*distribute the numbers*/
distribute(index_table,array,array_len,block_num,block_len);
/*search the number according to the index table*/
int target,result;
printf("which number you want to search:");
scanf("%d",&target);
result = index_search(index_table,array_len,block_num,block_len,target);
printf("%d is the %dth number\n",target,result+1);
/*release dynamically allocated memory*/
free(array);
return 0;
}
/*
**function:find_key
**description:finding the largest number of each block and reserve it in index_table[i].key
**parameter 1: the name of the index table
**parameter 2: the name of the array
**parameter 3: the length of the array
**parameter 4: the number of the block of the index table
**parameter 5: the length of each block
*/
void find_key(index * index_table,int * array,int array_len,int block_num,int block_len)
{
int i,j;
for (i = 0;i<block_num;i++)
{
index_table[i].key = array[i*block_len];
for (j = block_len*i+1;j<block_len*(i+1);j++)
{
if (j==array_len)
{
return;
}
if (index_table[i].key<array[j])
{
index_table[i].key = array[j];
}
}
}
}
/*
**function: distribute
**description: put the number of the array into the index table
**parameter 1: the name of the index table
**parameter 2: the name of the array
**parameter 3: the length of the array
**parameter 4: the number of the block of the index table
**parameter 5: the length of each block
*/
void distribute(index * index_table,int * array,int array_len,int block_num,int block_len)
{
int i,j;
for (i = 0;i<block_num;i++)
{
index_table[i].addr = i*block_len;
for (j = 0;j<block_len;j++)
{
if (i*block_len+j>=array_len)
{
return;
}
index_table[i].number[j] = array[i*block_len+j];
}
}
}
/*
**function: index_search
**description: finding the place of the target number
**parameter 1: the name of the index table
**parameter 2: the length of the array
**parameter 3: the number of the block of the index table
**parameter 4: the length of each block
**parameter 5: the number which you want to search
**return: the serial number of the target number in the array
*/
int index_search(index * index_table,int array_len,int block_num,int block_len,int target)
{
int i,j;
for (i = 0;i<block_num;i++)
{
if (target<=index_table[i].key)
{
break;
}
}
if (i==block_num)
{
printf("can not find this number!\n");
exit(0);
}
/*if the number is in the final block*/
if (i==block_num-1)
{
for (j = 0;j<(array_len-(block_num-1)*block_len);j++)
{
if (index_table[i].number[j]==target)
{
return (index_table[i].addr+j);
}
}
if (j==(array_len-(block_num-1)*block_len))
{
printf("can not find this number!\n");
exit(0);
}
}
else
{
for (j = 0;j<block_len;j++)
{
if (target==index_table[i].number[j])
{
return (index_table[i].addr+j);
}
}
if (j==block_len)
{
printf("can not find this number!\n");
exit(0);
}
}
}
以一开始举的例子为例:
输入1,3,2,6,9,8,13,15,19,32,查找值32
运行结果: