数据结构查找算法(二分查找)

二分查找

二分查找算法,说白了就是在有序的数组里面给予一个存在数组里面的值key,然后将其先和数组中间的比较,如果key大于中间值,进行下一次mid后面的比较,直到找到相等的,就可以得到它的位置。

  • 前提: 线性表中的记录必须是关键字有序(通常从小到大),线性表必须采用顺序存储。
  • 基本思想: 取中间记录作为比较对象,若给定值与中间记录的关键字相等,则查找成功;若给定值小于中间记录的关键字,则在中间记录的左半区继续查找;否则,在右半区查找。不断重复,直到查找成功或查找失败为止。
  • 复杂度\boldsymbol{O(log(n))}

二分算法步骤描述

前提:有序数组中查找关键词所在的位置

  1. 首先确定整个查找区间的中间位置 mid = strat+(end-strat)/2

  2. 用待查关键字key值与中间位置的关键字值进行比较;

    若相等,则查找成功

    若key小于a[k],则在前(左)半个区域继续进行折半查找\boldsymbol{arr[low,mid-1]}

    若key大于a[k],则在后(右)半个区域继续进行折半查找\boldsymbol{arr[mid+1,high]}

  3. 对确定的缩小区域再按折半公式,重复上述步骤。

二分查找的应用场景:

二分查找目的是在一堆数中找到指定的数。

使用二分查找这些数据需要有的特征(面试容易问):

  1. 存储在数组中。
  2. 有序的排列。

如果是链表就无法使用二分查找。

顺序数组是递增递减,是否有重复的数据没有关系。

二分查找的实现(递归算+非递归)

递归算

折半查找,递归实现(模板)

/*折半查找,递归实现*/  
template<class T>  
int Binary_Search(T *x, int N, T keyword)  
{  
    int low = 0, high = N-1,mid;  
    while(low <= high)  
    {  
        mid = (low + high)/2;  
        if(x[mid] == keyword)  
            return mid;  
        if(x[mid] < keyword)  
            low = mid + 1;  
         else  
            high = mid -1;  

    }  
    return -1;  
}  

折半查找,递归实现

/*折半查找,递归实现*/  
int binarySearch(int *arr , int low , int high , int target)//递归实现
{
	int middle = (low + high)/2;
	if(low > high)
		return -1;
	if(arr[middle] == target)
		return middle;
	if(arr[middle] > target)
		return binarySearch( arr , low , middle - 1 , target);
	if(arr[middle] < target)
		return binarySearch( arr , middle + 1 , high , target);
 
};

非递归实现

 /**
     * 二分查找普通实现。
     * @param srcArray 有序数组
     * @param key 查找元素
     * @return  不存在返回-1,存在返回对应的数组下标
     */
    
int binarySearch1(int a[], int n , int target)//循环实现
{
    int low = 0 ,high = n , middle;
    middle = (low + high)/2;
    if (key == a[middle]) {
        return mid;
    }
    
	while(low < high)
	{
	   middle = (low + high)/2;
       if(target == a[middle])
		   return middle;
	   else if(target > a[middle])
		   low = middle +1;
	   else if(target < a[middle])
		   high = middle;
	}
	return -1;
};

参考例子

#include<iostream>
using namespace std;
int binarySearch(int *arr , int low , int high , int target)//递归实现
{
	int middle = (low + high)/2;
	if(low > high)
		return -1;
	if(arr[middle] == target)
		return middle;
	if(arr[middle] > target)
		return binarySearch( arr , low , middle - 1 , target);
	if(arr[middle] < target)
		return binarySearch( arr , middle + 1 , high , target);
 
};
 
int binarySearch1(int a[], int n , int target)//循环实现
{
	int low = 0 ,high = n , middle;
	while(low < high)
	{
	   middle = (low + high)/2;
       if(target == a[middle])
		   return middle;
	   else if(target > a[middle])
		   low = middle +1;
	   else if(target < a[middle])
		   high = middle;
	}
	return -1;
};
 
int main()
{
	int a[10] = {5,6,7,8,9, 10 , 11, 12 ,13, 14};
	int index = binarySearch( a , 0 , 9 , 12);
	cout<<index<< endl;
	int index2 = binarySearch1(a,10,12);
	cout<<index2<< endl;
	system("pause");
}

后记:

查找和排序都是在程序设计中经常用到的算法,查找相对而言较为简单,不外乎顺序查找、二分查找、哈希表查找和二叉排序树查找。
在面试的时候,不管是用循环还是用递归,面试官都期待应聘者能够信手拈来写出完整的二分查找代码,否则可能连继续面试的兴趣都没有。
以上两句话引出自《剑指Offer:名企面试官精讲典型面试题》

  • 0
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
二分查找是一种常见的搜索算法,用于在有序数组或有序列表中快速定位特定值的位置。这种算法的基本思想是将目标值与数组中间元素进行比较,根据比较结果将搜索范围缩小一半,直到找到目标值或确定目标值不存在为止。 以下是二分查找算法的基本步骤: 1. 初始化左边界 left 和右边界 right,分别指向数组的第一个元素和最后一个元素。 2. 计算中间位置 mid,可以使用公式 mid = (left + right) / 2。 3. 比较中间位置的值与目标值 target: - 如果中间位置的值等于目标值,则找到目标值,返回索引。 - 如果中间位置的值大于目标值,则目标值可能在左半部分,更新右边界为 mid - 1。 - 如果中间位置的值小于目标值,则目标值可能在右半部分,更新左边界为 mid + 1。 4. 重复步骤 2 和步骤 3,直到找到目标值或搜索范围为空(即 left > right)。 以下是一个使用二分查找算法在有序数组中查找目标值的示例代码(使用递归实现): ```python def binary_search(arr, target, left, right): if left > right: return -1 mid = (left + right) // 2 if arr[mid] == target: return mid elif arr[mid] > target: return binary_search(arr, target, left, mid - 1) else: return binary_search(arr, target, mid + 1, right) ``` 你可以将目标值、数组以及左右边界作为参数传递给该函数来执行二分查找。如果目标值存在于数组中,该函数将返回目标值的索引;否则,返回 -1 表示未找到。 希望这能回答你的问题!如有其他疑问,请随时提问。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值