算法--二分法

一、思想

假设待查找序列和题目的要求之间的关系是单调递增的,先取区间的中心,判断该处函数值和题目标准值的大小关系,如果函数值偏小,那么应该在中心右侧的区间继续查找;如果函数值偏大 ,那么应该在中心左侧区间继续查找,直到找到对应的值或者区间缩小到左右端点之间不再包含其他数据结束。

(1)首先,从数组的中间元素开始搜索,如果该元素正好是目标元素,则搜索过程结束,否则执行下一步。

(2)如果目标元素大于/小于中间元素,则在数组大于/小于中间元素的那一半区域查找,然后重复步骤(1)的操作。

(3)如果某一步数组为空,则表示找不到目标元素。

二、使用条件

(1)待查找的序列区间单调有序(单调递增或单调递减都可以);

(2)待查找序列和题目的要求建立的函数关系单调有序;

三、示例代码

/** @function      dichotomy_find_table_from_max
	* @brief         二分查找算法,表中数据从大到小 
	* @param:     	 table: 表地址;
	* @param: 			 tableSize: 表长度;
	* @param: 				data: 要查找的数据
	* @return        -1:出现异常; 其他:数据在表中的位置
	*/
s8_t dichotomy_find_table_from_max(const s32_t* table, u8_t tableSize, s32_t data)  
{  
	s8_t  pos = 0;
	u8_t head,end;  
	u8_t i;  

	if(table == NULL)           return -1;
	if(0 == tableSize)					return -1;
	if(1 == tableSize)          return 0;
	
	head = 0;  
	end = tableSize-1 ;  
	i = 0; 
	
	if(data >= table[head]) 			
	{
		return head ;  
	}
	else if(data <= table[end])   
	{
		return end ; 
	}
	
	while(head < end)  
	{  
		pos = (head+end)/2;  

		if(data == table[pos]) 				break;  
		if((data<table[pos]) && (data>table[pos+1])) break;  
			
		/* 区分是上半区还是下半区 */
		if(data > table[pos])  end = pos ;  /* 上半区 */                    
		else head = pos ;     /* 下半区 */
			
		if(i++ > tableSize) break ;  
	}  

	if(head > end ) return -1;   

	return pos ;  
}  
  
  

/** @function      dichotomy_find_table_from_max
	* @brief         二分查找算法,表中数据从小到大 
	* @param:     	 table: 表地址;
	* @param: 			 tableSize: 表长度;
	* @param: 				data: 要查找的数据
	* @return        -1:出现异常; 其他:数据在表中的位置
	*/
s8_t dichotomy_find_table_from_min(const s32_t* table, u8_t tableSize, s32_t data)
{  
	s8_t  pos = 0;
	u8_t head,end;  
	u8_t i;  

	if(table == NULL)           return -1;
	if(0 == tableSize)					return -1;
	if(1 == tableSize)          return 0;
	
	head = 0;  
	end = tableSize-1 ;  
	i = 0;  

	if(data >= table[end]) 				return end ;  
	else if(data <= table[head])  return head;  

	while(head < end)  
	{  
		pos = (head+end)/2 ;  

		if(data == table[pos] ) 			break;  
		if((data<table[pos+1]) && (data>table[pos])) break;  			
			
		/* 区分是上半区还是下半区 */
		if(data > table[pos]) head = pos ;  //end = m ;                    
		else end = pos ;//head = m ;   
			
		if(i++ > tableSize) break ;  
	}  

	if(head > end ) return -1;   

	return pos ;  
} 

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值