当前位置: 首页 > news >正文

门户网站制作建设百度售后客服电话24小时

门户网站制作建设,百度售后客服电话24小时,虾皮跨境电商网站,做动态网站用什么语言二分查找 什么是二分查找&#xff1f; 二分查找是一种针对有序集合&#xff0c;每次将要查找的区间缩小一半&#xff0c;直到找到查找元素&#xff0c;或区间被缩小为0。 如何实现二分查找&#xff1f; 实现有3个注意点&#xff1a; 终止条件是 low < high 2.求中点的算…

二分查找

什么是二分查找?

二分查找是一种针对有序集合,每次将要查找的区间缩小一半,直到找到查找元素,或区间被缩小为0。

如何实现二分查找?

实现有3个注意点:

  1. 终止条件是 low <= high
    2.求中点的算法是 low + (high - low)/2
    3.low和high的更新是low=mid+1 即到更大的区间找, high=mid-1  即到更小的区间找。

非递归实现

        // 终止条件low>=high 当low=high时,mid=low+(high-low)/2=low=high,即没有等号将少比较一个点// 中点 mid = low + (high-low)/2 即以low为起点,计算low和high之间的中点// mid<value 找大区间 low=mid+1,mid>value,找小区间,high=mid-1public int binSearch(int[] arr,int n,int value){int low=0;int high=n-1;while(low<=high){int mid=low+((high-low)>>1);//int mid=low+(high-low)/2;if(arr[mid]<value){low=mid+1;} else if(arr[mid]>value){high=mid-1;} else{return mid;}}return -1;}

递归实现

// 二分查找的递归实现
public int bsearch(int[] a, int n, int val) {return bsearchInternally(a, 0, n - 1, val);
}private int bsearchInternally(int[] a, int low, int high, int value) {if (low > high) return -1;int mid =  low + ((high - low) >> 1);if (a[mid] == value) {return mid;} else if (a[mid] < value) {return bsearchInternally(a, mid+1, high, value);} else {return bsearchInternally(a, low, mid-1, value);}
}

二分查找有哪些局限性?

1.  二分查找依赖的是顺序表结构,也就是数组
2.  二分查找要求数据有序
3.  数据量太小不适合二分查找,除非每个数据的操作非常耗时,比如,数组中存储的都是长度超过 300 的字符串,如此长的两个字符串之间比对大小,就会非常耗时。
4.  数据量太大也不适合二分查找,因为数组需要占用大量连续的空间
5.  动态数据不适合二分查找,频繁的插入和删除在数组结构下效率很低

思考题

  1. 如何编程实现“求一个数的平方根”?要求精确到小数点后 6 位。
    可以用牛顿弦切法来求平方跟
    double number = 2; //待求平方根的数
    double xini = 10;//初始点
    while(xinixini - number > 1e-6) {
    xini = (number + xini
    xini)/2/xini;
    }
    // xini为平方根
  2. 我刚才说了,如果数据使用链表存储,二分查找的时间复杂就会变得很高,那查找的时间复杂度究竟是多少呢?
    链表不像数组那样支持随机访问,所以链表主要花的是查找第n个节点的访问的时间。
    第一次需要遍历n/2个节点,
    第二次需要遍历n/4个节点,
    第三次需要遍历n/8个节点,

n/2 + n/4 + n/8 + …
和约等于n,因此算法复杂度为O(n),单考虑到其他二分查找的额外操作,会比直接遍历循环查找慢一些。

二分查找有哪些变体问题?

对于有序数组中有重复元素而言二分查找通常有以下4个变体问题。
查找第一个值等于给定值的元素
查找最后一个值等于给定值的元素
查找第一个大于等于给定值的元素
查找最后一个小于等于给定值的元素

这些都是查找等于给定值的变体问题,想一想,你有什么思路可以实现呢?

如何实现变体的二分查找?

arr[mid]和value的值的比较有三种情况:大于,小于,等于
那对于问题1和2而言我们要特殊处理的等于的情况,
问题3要特殊处理大于等于的情况,
问题4要特殊处理小于等于的情况。
问题1的特殊处理逻辑:
等于的情况下,我们mid的下标有可能是0,即数组的第一个元素,那么我们直接返回mid就好了,
那其余情况就是mid>0,那么我们就看mid的前一个元素是否等于value,如果不等于,说明mid是第一个等于value的元素,也直接返回,
如果等于mid,那么我们就需要在前面的区间去查找了,即 high = mid - 1;

那问题2,3,4和1的处理思路类似,可以试着自己实现。

1

    public int binSearchFirst(int[] arr,int n,int value){int low=0;int high=n-1;while (low<=high) {int mid = low + (high - low) / 2;if(arr[mid]<value){low=mid+1;} else if(arr[mid]>value){high=mid-1;} else{// 需要特殊处理的是等于的情况// 1.看mid是否为第一个元素,是返回mid// 2.看mid的前一个元素是否等于value,不等于返回mid// 3.mid的前一个元素等于value,那么就应该去前面区间找,即 high = mid - 1;if(mid==0||arr[mid-1]!=value) {return mid;}high=mid-1;}}return -1;}

2

    public int binSearchFirst(int[] arr,int n,int value){int low=0;int high=n-1;while (low<=high) {int mid = low + (high - low) / 2;if(arr[mid]<value){low=mid+1;} else if(arr[mid]>value){high=mid-1;} else{// 需要特殊处理的是等于的情况// 1.看是mid否为最后一个元素,是返回mid// 2.看mid的后一个元素是否等于value,不等于返回mid// 3.mid的后一个元素等于value,那么就应该去后面区间找,即 low = mid + 1;if(mid==n-1||arr[mid+1]!=value) {return mid;}low=mid+1;}}return -1;}

3

    public int binSearchFirst(int[] arr,int n,int value) {int low = 0;int high = n - 1;while (low <= high) {int mid = low + (high - low) / 2;if (arr[mid] >= value) {// 主要处理大于等于的情况// 1.看mid是否为第一个元素,是返回mid// 2.看mid的前一个元素是否小于value,是返回mid// 3.前一个元素大于等于value,应该去前面区间找,即high=mid-1if(mid==0||arr[mid-1]<value){return mid;}high = mid - 1;} else {low = mid + 1;}}return -1;}

4

    public int binSearchFirst(int[] arr,int n,int value) {int low = 0;int high = n - 1;while (low <= high) {int mid = low + (high - low) / 2;if (arr[mid] <= value) {// 主要处理大于等于的情况// 1.看mid是否为最后一个元素,是返回mid// 2.看mid的后一个元素是否大于value,是返回mid// 3.后一个元素小于等于value,应该去后面区间找,即low=mid+1if(mid==n-1||arr[mid+1]>value){return mid;}low = mid + 1;} else {high = mid - 1;}}return -1;}

二分查找的实际应用场景?

绝大部分情况能用二分查找解决的问题我们更倾向使用散列表或二叉查找树,
那二分查找其实更适用于近似的查找(范围查找)问题,因为这类问题用上述数据结构都不容易实现。

思考题

我们今天讲的都是非常规的二分查找问题,今天的思考题也是一个非常规的二分查找问题。如果有序数组是一个循环有序数组,比如 4,5,6,1,2,3。针对这种情况,如何实现一个求“值等于给定值”的二分查找算法呢?

我们发现循环数组存在一个性质:以数组中间点为分区,会将数组分成一个有序数组和一个循环有序数组。
 
 如果首元素小于 mid,说明前半部分是有序的,后半部分是循环有序数组;
 如果首元素大于 mid,说明后半部分是有序的,前半部分是循环有序的数组;
 如果目标元素在有序数组范围中,使用二分查找;
 如果目标元素在循环有序数组中,设定数组边界后,使用以上方法继续查找。
 
 时间复杂度为 O(logN)。

http://www.ritt.cn/news/1618.html

相关文章:

  • 网站重构案例网页广告怎么做
  • 哈尔滨做平台网站平台公司哪家好百度快速收录提交工具
  • 泰国做那个视频网站友链
  • 临沂网站建设网站推广网页制作成品模板网站
  • 做网站运营的女生多吗巨量算数数据分析
  • 制作微信网站模板买转发链接
  • 杭州seo价格西安seo关键词推广
  • 河北邢台房价百度推广优化怎么做
  • 网站建设公司怎么赚钱济南计算机培训机构哪个最好
  • wordpress4.7更新说明正规网站优化公司
  • 培训网站源码wordpress软文街
  • 企业做网站建设遇到的问题网站制作郑州
  • 网站下面的站长统计很逗seo优化裤子关键词
  • 网页设计动态页面seo竞价培训
  • 同江佳木斯网站建设企业网站设计方案
  • 制作网站要花多少钱如何看网站搜索什么关键词
  • 网站怎么做淘宝客360线上推广
  • 网站建设的设计总结域名注册入口
  • wordpress搬运重庆百度seo公司
  • 小程序开发平台哪家质量好苏州百度快照优化排名
  • 付公司制作网站费怎么做凭证成都seo公司
  • 陕西网站建设设计百度高级搜索首页
  • 网站做淘宝客赚钱吗销售培训课程
  • wordpress好用的模板搜狗搜索引擎优化
  • 自己怎么做团购网站首页个人网站源码免费下载
  • 烟台软件优化网站百度竞价开户渠道
  • 上海网站改版沈阳网站推广优化
  • sql server做网站share群组链接分享
  • 网站维护工作加强服务保障满足群众急需i
  • 什么是网页站点聚名网官网登录