用C语言写二分查找,分块查找

二分查找
给一组有序的数组,要求找出其中一个元素,并输出此元素的位置,下面用二分查找
来做,二分查找的效率极高。举个例子,若让你猜一个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");
}
  • 2
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值