二分查找的两种实现方式

笔者在这里给出二分查找的两种实现方式。

一. 第一种是健忘版的二分查找,即不管是否已经找到target,查找算法都继续对表进行再分,直到剩下的表的长度为1。

递归实现如下:

Error_code recursive_binary_1(const Ordered_list &the_list, const Key &target, int bottom, int top, int &position) {
	Record data;
	if (bottom < top) {
		int mid = (bottom+top)/2;
		the_list.retrieve(mid, data); //获取mid位置的值并赋给data
		//注意下面两个语句不是对称的
		if (data < target) return recursive_binary_1(the_list, target, mid+1, top, position);
		else return recursive_binary_1(the_list, target, bottom, mid, position);
	}
	else if (top < bottom) return not_present;
	else {
		position = bottom;
		the_list.retrieve(position, data);
		if (data == target) return success;
		else return not_present;
	}
}

非递归实现如下:

Error_code recursive_binary_1(const Ordered_list &the_list, const Key &target, int &position) {
	Record data;
	int bottom = 0, top = the_list.size()-1;
	while (bottom < top) {
		int mid = (bottom+top)/2;
		the_list.retrieve(mid, data);
		if (data < target) bottom = mid+1;
		else top = mid;
	}
	else if (top < bottom) return not_present;
	else {
		position = bottom;
		the_list.retrieve(position, data);
		if (data == target) return success;
		else return not_present;
	}
}

需要注意的是健忘版的二分查找在二分时bottom和top的更新不是对称的,上面的条件总是会把mid放入两个区间中较低的一个,即在整个查找过程中bottom<=mid<top。上面的二分查找是一种简单形式的二分查找,它做了很多不必要的重复,因为它不能再继续重复前识别已找到了目标。

二. 第二种是识别想等的二分查找,即在继续二分前判断当前的值是否等于target,减少不必要的重复。

递归实现如下:

Error_code recursive_binary_2(const Ordered_list &the_list, const Key &target, int bottom, int top, int &position) {
	Record data;
	if (bottom <= top) {
		int mid = (bottom+top)/2;
		the_list.retrieve(mid, data); //获取mid位置的值并赋给data
		if (data == target) return {
			position = mid;
			success;
		}
		//下面的递归语句是对称的了
		if (data < target) return recursive_binary_2(the_list, target, mid+1, top, position);
		else return recursive_binary_2(the_list, target, bottom, mid-1, position);
	}
	return not_present;
}

非递归实现如下:

Error_code recursive_binary_1(const Ordered_list &the_list, const Key &target, int &position) {
	Record data;
	int bottom = 0, top = the_list.size()-1;
	while (bottom <= top) {
		position = (bottom+top)/2;
		the_list.retrieve(position, data);
		if (data == target) return success;
		if (data < target) bottom = position+1;
		else top = position-1;
	}
	return not_present;
}
时间: 2024-10-04 03:48:57

二分查找的两种实现方式的相关文章

二分查找的两种实现方式(JAVA)

二分查找又称折半查找,优点是比较次数少,查找速度快,平均性能好:其缺点是要求待查表为有序表,且插入删除困难.因此,折半查找方法适用于不经常变动而查找频繁的有序列表.首先,假设表中元素是按升序排列,将表中间位置记录的关键字与查找关键字比较,如果两者相等,则查找成功:否则利用中间位置记录将表分成前.后两个子表,如果中间位置记录的关键字大于查找关键字,则进一步查找前一子表,否则进一步查找后一子表.重复以上过程,直到找到满足条件的记录,使查找成功,或直到子表不存在为止,此时查找不成功. 条件是:1.必须

c#二分查找的两种方式

其实:两种方式的实现结果一样,却体现出了不同的思考过程: 地中方式,是在一个while循环中,每次从中间找,不断的去改变low 和 high的 位置,然后求他们的中间位置,知道low=high=0:如果还没有知道值,就直接返回-1: /// <summary> /// 二分查找方式 /// </summary> /// <param name="arr"></param> /// <param name="target&q

#1128 : 二分&#183;二分查找 ( 两种方法 先排序在二分O(nlogN) + 直接二分+快排思想O(2N) )

#1128 : 二分·二分查找 时间限制:10000ms 单点时限:1000ms 内存限制:256MB 描述 Nettle最近在玩<艦これ>,因此Nettle收集了很多很多的船(这里我们假设Nettle氪了很多金,开了无数个船位).去除掉重复的船之后,还剩下N(1≤N≤1,000,000)种不同的船.每一艘船有一个稀有值,任意两艘船的稀有值都不相同,稀有值越小的船越稀有,价值也就越高. Nettle现在通过大建又造出了一艘船,他想知道这艘船是不是重复的.如果是重复的,那么这艘船在Nettle所

二分查找的两种写法

bool Bin_Search(const int *pre, int low, int high, const int key) { while(low < high) //注意 { int mid = low + ((high-low)>>1); if(pre[mid] == key) return true; else if(pre[mid] < key) low = mid + 1; else high = mid; //注意 } return false; } bool

struts2+spring的两种整合方式

借助于Spring插件(Struts2-spring-plugin-XXX.jar),我们可以非常简单地完成Spring和Struts2的整合,这种整合包括让Action自动装配Spring容器中的Bean,以及让Spring管理应用中的Action两种方式,不管采用哪种方式,完成Struts2和Spring的整合都是非常简单的,而且差别不大.一旦在Web应用中安装了Spring插件,即可充分利用该插件提供的功能: 1,可以通过Spring来创建所有的Action,Interceptor和Res

Oracle数据库服务器的两种连接方式

oracle提供了两种数据库连接方式,一种是专有连接方式,另一种是共享连接方式.区别在于专有连接方式是一个用户对应一个数据库服务器进程,而共享服务器连接方式是多个用户可以不定向轮流使用一个服务器进程.oracle推荐专有连接,一个session对应一个服务器进程,会减少竞争,对于较长事务很有用,但是会耗费PGA资源;共享连接方式对于事务执行时间短且服务器资源受限的系统是有利的.对于该使用哪种连接方式,自己权衡. 我们可以通过dbca设置数据库的连接方式: 当然我们也可以通过修改参数shared_

列表查找的两种方法

列表查找:从列表中查找指定元素 输入:列表.待查找元素 输出:元素下标或未找到元素 列表查找的两种方法: 顺序查找 从列表的第一个元素开始,顺序进行搜索,直到找到为止. 二分查找 (大前提有序)从有序列表的候选区[0:n]开始,通过对待查找的值与候选区中间值的比较,可以使候选区减少一半. 1.顺序查找代码:(时间复杂度为O(n)) def linear_search(data_set, value): for i in range(len(data_set)): if value == data

数据库持久化的两种实现方式

对数据库服务里的数据进行持久化存储,既可以做数据备份,也方面数据传输. 目前主要有两种实现方式: 一.创建快照 Mysql快照Mysql的dump工具,可以将数据导出为.sql文件,通过这个sql文件,可以作数据恢复. $ mysqldump -h xxx -uroot -p databasename > ~/data_backup/database.sql Redis的rdbredis客户端下发送save/bgsave指令,会创建rdb文件.默认文件名为dump.rdb 127.0.0.1:6

Java连载66-数组的两种初始化方式

一.数组 1.数组中存储元素的类型是统一的,每一个元素在内存中所占用的空间大小是相同的,知道数组的首元素的内存地址,要查找的元素只要知道下标,就可以快速的计算出偏移量,通过首元素内存地址加上偏移量,就可以快速计算出要查找元素的内存地址.通过内存地址快速定位该元素,所以数组查找元素的效率较高. 2.随机的对数组进行增删元素,当增加元素的时候,为了保证数组中元素在空间存储上是有序的,所以被添加元素位置后面的所有元素都要向后移动,删除元素也是,后面所有的元素要向前移动,所以数组的增删元素?效率很低.