考研数据结构之查找(9.2)——折半查找法(C表示)

算法思想

前提条件:折半查找要求线性表是有序的,即表中记录按关键字有序的。

折半查找的基本思路:设R[low, .. high]是当前的查找区间,首先确定该区间的中间位置mid=(low+high)/2;,然后将待查的k值与R[mid]比较,若相等,则查找成功,并返回该位置,否则需确定新的查找区间。若R[mid]>k,则由表的有序性可知R[mid, ..,. high]均大于 k,因此若表中存在关键字等于k的记录,则该记录必定是在mid左边的子表R[low,.., mid-1]中, 故新的查找区间是左子表R[low,... ,mid-1]。类似地,若R[mid]<k,则要查找的k必在mid的右子表R[mid+1, ... ,high]中,即新的查找区间是右子表R[mid+1, ... high]. 递归地处理新区间,直到子区间的长度小于1时查找过程结束。

代码

核心代码:

/* 折半查找法 */
int Bsearch(int R[],int low,int high,int k) {
	int mid;
	while(low<=high) { // 当子表长度大于等于1时进行循环
		mid=(low+high)/2;// 取表中间位置
		if(R[mid]==k) { // 找到后返回元素的位置
			return mid;
		} else if(R[mid]>k) { // 说明R[low,...,mid-1]中查找
			high=mid-1;
		} else { // 说明需要在R[mid+1,...,high]中查找
			low=mid+1;
		}
	}
	return 0;// 若查找不成功返回0
}

完整代码:

#include<stdio.h>

/* 打印数组元素 */
void print(int nums[],int n) {
	printf("\n");
	for(int i=0; i<n; i++) {
		printf("%d\t",nums[i]);
	}
	printf("\n");
}

/* 折半查找法 */
int Bsearch(int R[],int low,int high,int k) {
	int mid;
	while(low<=high) { // 当子表长度大于等于1时进行循环
		mid=(low+high)/2;// 取表中间位置
		if(R[mid]==k) { // 找到后返回元素的位置
			return mid;
		} else if(R[mid]>k) { // 说明R[low,...,mid-1]中查找
			high=mid-1;
		} else { // 说明需要在R[mid+1,...,high]中查找
			low=mid+1;
		}
	}
	return 0;// 若查找不成功返回0
}

int main() {
	int nums[]= {1,2,3,4,5,6,7,8,9};
	int n=9;// nums数组的长度
	print(nums,n);

	/* 查找 */
	int key=2;
	int r=Bsearch(nums,0,n-1,key);
	printf("查找结果(成功返回下标,失败返回-1):%d",r);

	return 0;
}

运行结果:

折半查找的过程可以用二叉树来表示。把当前查找区间的中间位置作为根,左子表和右子表的记录分别作为根的左子树和右子树。

折半查找的比较此时即为从根节点到待查找元素所经过的结点数,其比较次数最多的情况即为一直走到叶子结点的情况。因此,算法的时间复杂度可以用树的高度来表示。

即对于有n个记录的查找表,进行折半查找的时间复杂度为log2n,折半查找的平均查找长度近似为log2(n+1)-1。

如:以序列{1,2,3,4,5,6,7,8,9,10,11}做一棵判定树。

例题:画出对于含有13个关键字的有序表进行折半查找的判定树,并分别求其在等概率查找表中元素时,查找成功和不成功的平均查找长度ASL1、ASL2。

  • 3
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值