二分查找又称折半查找,首先,假设表中元素是按升序排列,将 表中间位置的关键字与查找关键字比较:

  1. 如果两者相等,则查找成功;
  2. 否则利用中间位置将表分成前、后两个子表:
    1)如果中间位置的关键字大于查找关键字,则进一步查找前一子表
    2)否则进一步查找后一子表 重复以上过程,直到找到满足条件的记录,使查找成功,或直到子表不存在为止,此时查找不成功。

例如:target = 200
arr = [-1,2,5,20,90,100,320]

使用二分查找,从arr中查找target是否存在

  1. 取中间位置为20 ,20 < 200
  2. 缩小查找空间 [90,100,320],二分查找中间位置100 < 200
  3. 缩小查找空间[320,320],begin == end
  4. 未找到 200,返回失败

问题描述如下:
已知一个排序数组A,如 A = [-1, 2, 5, 20, 90, 100, 207, 800], 另外一个乱序数组B,如 B = [50, 90, 3, -1, 207, 80], 求B中的任意某个元素,是否在A中出现,结果存储在数组C中,出现 用1代表,未出现用0代表,如,C = [0, 1, 0, 1, 1, 0]。

以上过程如果使用暴力搜索,则需要O(n*m)即O(n^2);
这里使用二分查找则仅仅需要O(log2n)的时间复杂度:
n/2 + n/4 + … + n/2^k (k为循环的次数)
由于你n/2^k (取最坏的情况,最后一次仅剩下一个数)
即令n/2^k=1
可得k=log2n,(是以2为底,n的对数)
所以时间复杂度可以表示O(h)=O(log2n)

递归实现如下:

bool find_part(std::vector<int> arr, int begin, int end, int target) {if (begin > end) {//结束条件return false;}int mid = (begin + end) / 2;if (arr[mid] == target) {return true;} else if (arr[mid] > target) {return find_part(arr, begin, mid -1, target);} else {return find_part(arr, mid + 1, end, target);}
}std::vector<int> get_result(std::vector<int> arr, std::vector<int> target) {std::vector<int> v;for (int i = 0;i < target.size(); ++i) {int result = find_part(arr,0,arr.size() - 1, target[i]);v.push_back(result);}return v;
}

非递归实现:

std::vector<int> find_part_norecur(std::vector<int> arr1, std::vector<int> target) {std::vector<int> result;for (int i = 0;i < target.size(); ++i) {int begin = 0;int end = arr1.size();while(begin <= end) {int mid = (begin +  end) / 2;if(arr1[mid] == target[i]) {result.push_back(1);break;} else if (arr1[mid] > target[i]) {end = mid - 1;} else {begin = mid + 1;}}if (begin >= end){result.push_back(0);}}return result;
}

测试代码如下:

#include <iostream>
#include <vector>using namespace std;bool find_part(std::vector<int> arr, int begin, int end, int target) {if (begin > end) {return false;}int mid = (begin + end) / 2;if (arr[mid] == target) {return true;} else if (arr[mid] > target) {return find_part(arr, begin, mid -1, target);} else {return find_part(arr, mid + 1, end, target);}
}std::vector<int> get_result(std::vector<int> arr, std::vector<int> target) {std::vector<int> v;for (int i = 0;i < target.size(); ++i) {int result = find_part(arr,0,arr.size() - 1, target[i]);v.push_back(result);}return v;
}std::vector<int> find_part_norecur(std::vector<int> arr1, std::vector<int> target) {std::vector<int> result;for (int i = 0;i < target.size(); ++i) {int begin = 0;int end = arr1.size();while(begin <= end) {int mid = (begin +  end) / 2;if(arr1[mid] == target[i]) {result.push_back(1);break;} else if (arr1[mid] > target[i]) {end = mid - 1;} else {begin = mid + 1;}}if (begin >= end){result.push_back(0);}}return result;
}int main(int argc, char const *argv[])
{std::vector<int> arr1;std::vector<int> target;int n;cin >> n;for (int i = 0;i < n; ++i) {int tmp;cin >> tmp;arr1.push_back(tmp);}int t;cin >> t;for (int i = 0;i < t; ++i) {int tmp;cin >> tmp;target.push_back(tmp);} std::vector<int> result;// result = get_result(arr1, target);result = find_part_norecur(arr1,target);for (int i = 0;i < result.size(); ++i) {cout << result[i] << " ";}return 0;
}

输出如下:

#输入序列数组
5
2 3 4 5 6
#输入目标数组
3
1 3 5
#输出
0 1 1

二分法:二分查找(递归+非递归)实现相关推荐

  1. 【Java数据结构与算法】第十七章 二分查找(非递归)和分治算法(汉诺塔)

    第十七章 二分查找(非递归)和分治算法(汉诺塔) 文章目录 第十七章 二分查找(非递归)和分治算法(汉诺塔) 一.二分查找 1.思路 2.代码实现 二.分治算法(汉诺塔) 1.概述 2.汉诺塔 一.二 ...

  2. 二分查找算法(非递归)

    1.二分查找算法(非递归)介绍 前面我们讲过了二分查找算法,是使用递归的方式,下面我们讲解二分查找算法的非递归方式 二分查找法只适用于从有序的数列中进行查找(比如数字和字母等),将数列排序后再进行查找 ...

  3. 二分查找原理非递归与递归实现【转载】

    二分查找 实现查找指定数值在元素有序的数组中存储的位置(索引),返回该位置(索引). 解题步骤: 定义3个用来记录索引值的变量,变量min记录当前范围最小索引值,初始值为0:变量max记录当前范围最大 ...

  4. c语言折半查找递归程序,C语言数据结构中二分查找递归非递归实现并分析

    C语言数据结构中二分查找递归非递归实现并分析 前言: 二分查找在有序数列的查找过程中算法复杂度低,并且效率很高.因此较为受我们追捧.其实二分查找算法,是一个很经典的算法.但是呢,又容易写错.因为总是考 ...

  5. python递归实现二分查找_python二分查找算法的递归实现

    本文实例讲述了python二分查找算法的递归实现方法.分享给大家供大家参考,具体如下: 这里先提供一段二分查找的代码: def binarySearch(alist, item): first = 0 ...

  6. python递归实现二分查找_python二分查找算法的递归实现方法

    本文实例讲述了python二分查找算法的递归实现方法.分享给大家供大家参考,具体如下: 这里先提供一段二分查找的代码: def binarySearch(alist, item): first = 0 ...

  7. 一文彻底搞定二叉树的前序、中序、后序遍历(图解递归非递归)

    前言 大家好,我是bigsai,在数据结构与算法中,二叉树无论是考研.笔试都是非常高频的考点内容,在二叉树中,二叉树的遍历又是非常重要的知识点,今天给大家讲讲二叉树的层序遍历. 这部分很多人可能会但是 ...

  8. java 建树源码_Java实现的二叉树常用操作【前序建树,前中后递归非递归遍历及层序遍历】...

    import java.util.ArrayDeque; import java.util.Queue; import java.util.Stack; //二叉树的建树,前中后 递归非递归遍历 层序 ...

  9. 快排递归非递归python_Python递归神经网络终极指南

    快排递归非递归python Recurrent neural networks are deep learning models that are typically used to solve ti ...

  10. 二叉树的深度(前序 中序 后序 递归非递归搜素)、广度、搜索 C++

    a b c 使用 1 2 3 表示 /* 描述:二叉树的深度(前序 中序 后序 递归非递归搜素).广度.搜索 作者:jz 日期:20140819 */ #include<stdio.h> ...

最新文章

  1. 3.3. shutdown
  2. final 修饰方法参数
  3. 【面试招聘】有哪些好的秋招经验分享?数据、算法岗的几点经验分享
  4. 文末福利 | Python3 网络爬虫:老板,需要特殊服务吗?
  5. stm32设置内部上拉电阻_不知道STM32的GPIO8种模式如何设置?-------看这里
  6. P2146 [NOI2015] 软件包管理器
  7. tfidf处理代码_tfidf.txt
  8. go调用python3_在python3中使用google的protobuf以及gRPC-Go语言中文社区
  9. java静态初始化模块,在静态初始化程序块中加载java属性
  10. 大厂爱考的 Binder 系统服务注册问题怎么破?
  11. 生日快乐编程代码_「世界上最好的编程语言」,刚刚度过了25周岁生日
  12. h5页面自定义字体_H5页面中常见的字体有哪些
  13. Python设计模式:责任链模式
  14. matlab解反应扩散方程,反应扩散方程Matlab编程
  15. 网页前端上传文件,后端接受并处理文件
  16. 详解ARM的AMBA设备中的DMA设备(Linux驱动之DMA)
  17. 入行数据分析要知道什么是概括性度量
  18. 计算机组装方案i5,3000元预算方案i5 8400/GTX1050Ti装配配置清单推荐
  19. win10更新后开不了机_win10开机关机正常,重启特别慢问题排查
  20. vscode中建立vue项目

热门文章

  1. -变量,进制,数据类型,标识符
  2. Linux驱动框架之framebuffer驱动框架
  3. 奇妙的算法之LCS妙解
  4. 软考之路-网络攻击:主动攻击和被动攻击
  5. html中锚点的应用【本页面跳转】
  6. 携号转网:欢迎比阻挠更为有效
  7. html无规律卡片布局,如何实现同等间隙的卡片布局
  8. php smarty关闭缓存,php+Smarty的缓存操作
  9. dblink oracle mysql,Oracle dblink的使用
  10. linux fork 目录,linux fork()理解