1.分块查找:
错误代码:
#include <stdio.h>
#define maxSize 100
typedef struct
{
int key;
int low,high;
}IndexElem;
IndexElem index[maxSize];
int IndexSearch(IndexElem index[],int m,int r[],int n,int key)
{
int low, high,mid,i;
low = 0,high = n-1;
while(low <= high)
{
mid = (low + high)/2;
if(r[mid]>=key)//注意这里是=,对比折半插入排序是不同的,因为此处相同表示就该在mid处查找,亦即high+1处查找
high = mid - 1;
else
low = mid + 1;
}
i = index[high + 1].low;
while(i<=index[high+1].high)
if(index[i].key == key)
return i;
return 0;
}
int GetMax(int r[],int low,int high)
{
int max = r[low];
int i;
for(i = low+1; i <= high; ++i)
if(r[i] > max)
max = r[i];
return max;
}
int main()
{
int r[8] = { 49,38,65,97,76,13,27,49 };
int n = 8;
int m = 0,i,j,k,key = 13,step = 2;
//建立索引
if(n <= step)
{
index[m].key = GetMax(r,0,n-1);
index[m].low = 0;
index[m].high = n - 1;
m++;
}
else
{
k = n/step;//可以分成的块数
int p,q;
for(i = 1;i <= k;++i)
{
q = i*step;
p = q - step;
index[m].high = q-1;
index[m].low = p;
index[m].key = GetMax(r,p,q-1);
m++;
}
if(n%step != 0)
{
index[m].low = k*step;
index[m].high = n-1;
index[m].key = GetMax(r,k*step,n-1);
m++;
}
}
j = IndexSearch(index,m,r,n,key);
if(j == 0)
printf("Failure!");
else
printf("%d is %dth number",r[j],j+1);
system("pause");
return 0;
}
错误批改:
#include <stdio.h>
#define maxSize 100
typedef struct
{
int key;
int low,high;
}IndexElem;
IndexElem index[maxSize];
int IndexSearch(IndexElem index[],int m,int r[],int n,int key)
{
int low, high,mid,i;
low = 0,high = n-1;//m-1
while(low <= high)
{
mid = (low + high)/2;
if(r[mid]>=key)//注意这里是=,对比折半插入排序是不同的,因为此处相同表示就该在mid处查找,亦即high+1处查找
high = mid - 1;
else
low = mid + 1;
}
i = index[high + 1].low;
while(i<=index[high+1].high)
if(index[i].key == key)//r[i]
return i;//缺少循环变量的递加,造成死循环,应增加语句i++
return 0;
}
int GetMax(int r[],int low,int high)
{
int max = r[low];
int i;
for(i = low+1; i <= high; ++i)
if(r[i] > max)
max = r[i];
return max;
}
int main()
{
int r[8] = { 49,38,65,97,76,13,27,49 };
int n = 8;
int m = 0,i,j,k,key = 13,step = 2;
//下面这一块代码实际理解错了分块查找的条件,首先r[]数组分成的字块要分块有序
//所谓分块有序指的是第二个子表的所有关键字要大于第一个子表最大的关键字
//正确的方法为让其合法的输入一个数组r,然后再进行分块
//定义两个变量start=0和end=1当end<=n-1时做一个循环:
//当end比start所指的数组元素大时,low=start,high=end-1
//退出循环当start <= n-1时,将r数组剩下的元素并入即可
//当然方法有很多,即使是不合法输入的r也可以分块成合法的只需要增加条件r[end]大于前一个子表中最大的元素,
//如果小于则停止分块结束,并提示输入不合法
//建立索引
if(n <= step)
{
index[m].key = GetMax(r,0,n-1);
index[m].low = 0;
index[m].high = n - 1;
m++;
}
else
{
k = n/step;//可以分成的块数
int p,q;
for(i = 1;i <= k;++i)
{
q = i*step;
p = q - step;
index[m].high = q-1;
index[m].low = p;
index[m].key = GetMax(r,p,q-1);
m++;
}
if(n%step != 0)
{
index[m].low = k*step;
index[m].high = n-1;
index[m].key = GetMax(r,k*step,n-1);
m++;
}
j = IndexSearch(index,m,r,n,key);
if(j == 0)
printf("Failure!");
else
printf("%d is %dth number",r[j],j+1);
system("pause");
return 0;
}
正确代码:
#include <stdio.h>
#include <stdlib.h>
#define maxSize 100
typedef struct
{
int key;
int low, high;
}IndexElem;
int IndexSearch(IndexElem index[], int m, int r[], int n, int key)
{
int low, high, mid, i;
low = 0, high = m - 1;
while (low <= high)
{
mid = (low + high) / 2;
if (index[mid].key >= key)//注意这里是=,对比折半插入排序是不同的,因为此处相同表示就该在mid处查找,亦即high+1处查找
high = mid - 1;
else
low = mid + 1;
}
i = index[high + 1].low;
while (i <= index[high + 1].high)
{
if (r[i] == key)
return i;
i++;
}
return 0;
}
int main()
{
int r[18] = { 22,12,13,8,9,20,33,42,44,38,24,48,60,58,74,49,86,53 };
int n = 18;
int m = 3, i, j, key = 12;
//建立索引
IndexElem index[maxSize] = { {22,0,5},{48,6,11},{86,12,17} };
j = IndexSearch(index, m, r, n, key);
if (j == 0)
printf("Failure!");
else
printf("%d is %dth number", r[j], j + 1);
system("pause");
return 0;
}
来源:https://blog.csdn.net/weixin_42545675/article/details/99102907