二分查找
给一组有序的数组,要求找出其中一个元素,并输出此元素的位置,下面用二分查找
来做,二分查找的效率极高。举个例子,若让你猜一个1—100之间的数,首先你肯定
会猜50,因为这样折半的猜才会使猜的次数最少。二分查找的思想也是同样,先找到
最中间的元素,跟要找的元素比较,这样就排除了一半的元素,然后将包含要找的元
素的那一半数再分成两半,直到找到需要的那个数,这种方法的缺点是只能用于一组
有顺序的数,无序则不可以用。
//二分查找
int binary_search(int key, int a[], int sz)
{
int left = 0;
int right = sz - 1;
int mid = (left + right) / 2;//中间元素的下标
while (left<=right)
{
mid = (left + right) / 2;
if (key > a[mid])//将中间元素和关键数比较
left=mid+1;
else if (key < a[mid])
right = mid - 1;
else
break;
}
if (left <= right)
{
return mid;//找到了,返回下标
}
else
return -1;//没找到
}
int main()
{
int i = 0;
int key = 11;
int a[10] = { 2, 3, 5, 6, 7, 8, 9, 12, 13, 35 };//有序的一组数
int sz = sizeof(a) / sizeof(a[0]);
int ret = 0;
ret = binary_search(key, a, sz);
if (ret >= 0)
{
printf("找到了,下标为%d", ret);//返回关键数的下标
}
else
printf("找不到");
return 0;
}
分块查找,也叫索引顺序查找
将待查的元素均匀的分成块,块间按大小排序,块内不排序,所以要建立一个块的最
大(或最小)关键字表,称为索引表。
索引存储结构
存储节点信息时,建立索引表,索引表含有若干个索引项,索引项的一般形式:(关字,
地址),关键字表示表示一个节点,地址是指向节点的信息,可以通过索引的方法来
操作相应位置的数据。
例如
采用分块查找法再有序表中查找一个关键数。总元素个数为15个,将给出的15个数按
关键字大小分成了3块,这15个数的排列是一个有序序列,也可以给出无序序列,但必
须满足分在第一块中任意数都小于第二块中的所有数,第二块中的所有数都小于第三块
中的所有数。当要查找关键字为key的元素时,先用顺序查找在已建好的索引表中查出
key所在的块中,再在对应的块中顺序查找key,若key存在,则输出其相应位置否则输
出提示信息。
//分块查找
struct Index //定义块的结构
{
int key; //块的关键字
int start; //块的起始值
int end; //块的结束值
}Index_table[4]; //定义结构体数组
//自定义函数实现分块查找
int block_search(int key, int a[])
{
int i = 0;
int j = 0;
i = 1;
while (i <= 3 && key > Index_table[i].key) //确定在哪个块中
i++;
if (i > 3) //大于分得的块中,则返回0
{
return 0;
j = Index_table[i].start; //j等于块范围的起始值
while (j <= Index_table[i].end&&a[j] != key;//在确定的快内进行顺序查找
j++;
if (j > Index_table[i].end)//如果大于块范围的结束值,则说明没有要查找的数
j = 0; //j置0
return j;
}
int main()
{
int i = 0;
int j = 0;
int k = 0;
int key = 0;
int a[16] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 12, 13, 14, 15, 16, 17 };
for (i = 1; i <= 3; i++)
{
Index_table[i].start = j + 1; //确定每个块范围的起始值
j = j + 1;
Index_table[i].end = j + 4; //确定每个块范围的结束值
j = j + 4;
Index_table[i].key = a[j]; //确定每个块范围中元素的最大值
}
printf("请输入要查找的数字:");
scanf("%d", &key);
k = block_search(key, a);
if (k != 0)
printf("查找成功,其位置是%d\n",k);
else
printf("查找失败\n");
}