【前置知识】

二分查找是对有序数组(向量)而言的,所以在使用二分查找前要确保数组已经是顺序的(用到排序算法)。

【二分查找原理】

聚会时通常会玩猜数字的游戏:

  1. 先由坐庄的人来写一个数字(比如在1~1000之内)
  2. 让大家轮流猜,并告诉大家正确数字比当前猜的数字大或者小
  3. 每猜一次范围就会缩小,最后猜中的人倒霉挨罚

二分查找要求只能猜中位数,每次让猜的范围缩小一半,这样很快就能猜中,也即很快能获得查找结果。

【二分查找原理概括】

通过每次选取位于当前范围的中间元素与要查找的元素进行比较,让每次查找范围缩小一半,从而迅速获得查找结果。

【查找操作的作用/目的】

我们进行查找操作时的目的是在一个数组中或者在数组的某一范围中找到是否有这个元素,如果有就获取这个元素所在的位置,如果没有就告诉我们没有。这样就有了查找操作的输入输出。

查找操作的输入:要查找的数组A,要查找的元素a,查找范围[lo,hi)    注意是左闭右开的区间

查找操作的输出:如果查找成功返回元素所在位置(即编号、下标),如果失败返回-1(通常约定,-1表示所进行的操作失败了)

【二分查找代码实现】

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;namespace binsearch
{class Program{static void Main(string[] args){int[] A = new int[30];Random ra = new Random();for (int i = 0; i < 30; i++){A[i] = ra.Next(40);}Program ps = new Program();ps.bubblesortB(ref A);Console.WriteLine("排序结果:");foreach (int a in A){ Console.Write(a + " ");}int key = ps.BinSearch(A, 10, 0, A.Length);Console.WriteLine("\n查找结果:"+key);Console.ReadKey();}public int BinSearch(int[]A,int a, int lo,int hi)//查找范围[lo,hi){while (lo<hi){int middle = lo + ((hi - lo) >> 1);if (a < A[middle]){hi = middle;//新的查找范围[lo,middle)}else if (a == A[middle]){return middle;//找到编号middle}else{lo = middle + 1;//新的查找范围[middle+1,hi)}}return -1;}//冒泡排序 https://blog.csdn.net/enternalstar/article/details/103400089public void bubblesortB(ref int[] A){bool isSorted = false;int m = 0;for (int i = 0; isSorted == false; i++){isSorted = true;for (int j = 0; j < A.Length - 1 - i; j++){if (A[j] > A[j + 1]){int temp = A[j];A[j] = A[j + 1];A[j + 1] = temp;isSorted = false;}}}}}
}

【实现结果】(查找元素10)

【考虑有相同元素的情况】

如果我们要查找的元素在数组中有多个,该怎么办呢?

上文现实的算法是返回任意一个元素位置即可,如果要返回最大的位置或者最小的位置呢?也即我们对输出增加了一条新的要求,如果有多个相同元素,返回元素最大(或者最小)的位置。

最简单的方法是先找到有目标元素的位置,再在这个元素左边找最小的位置,右边找最大的位置。

【元素相同情况——改进代码实现】

       public int BinSearch2(int[] A, int a, int lo, int hi)//查找范围[lo,hi){int key=-1;while (lo < hi){int middle = lo + ((hi - lo) >> 1);if (a < A[middle]){hi = middle;//新的查找范围[lo,middle)}else if (a == A[middle]){key= middle;//找到编号middlebreak;}else{lo = middle + 1;//新的查找范围[middle+1,hi)}}//获得最小的位置//while(key-1>-1&&a == A[key - 1])//    key--;//获得最大的位置while(key+1<A.Length&&a == A[key+1])key++;return key;}

【改进实现结果】(查找元素10)

【要求不同的输出结果】

有其他输出要求时,如:查找第一个大于等于某个数的位置;查找数组中某个数的最小位置,没有返回-1;查找数组中某个数的出现次数等,在不特意要求效率的情况下,都可以用上述改进思路顺畅实现。

【要求效率的情况】

要求输出:如果有相同的元素,返回元素的最大位置。如果没找到元素,返回小于且距离该元素最近的元素的位置。

【要求效率的情况——代码实现】

 public int BinSearch3(int[] A, int a, int lo, int hi)//查找范围[lo,hi){while (lo < hi)//循环不能提前退出,只有在lo=hi时才退出{int middle = lo + ((hi - lo) >> 1);if (a < A[middle])//由三个分支改为两个分支{hi = middle;//新的查找范围[lo,middle)//hi在不断缩小,但A[hi]>a}else//a>=A[middle]{lo = middle + 1;//新的查找范围[middle+1,hi)//lo在不断增大,但A[lo-1]<=a,退出时lo=hi,A[lo]=A[hi]>a}}return --lo;}

【实现结果】

【参考】

[1]邓俊辉.数据结构(c++版)第三版

[2]https://blog.csdn.net/yefengzhichen/article/details/52372407

[3]https://blog.csdn.net/sunmenggmail/article/details/7540970

二分查找之C#实现详解相关推荐

  1. java二分查找法_java算法之二分查找法的实例详解

    java算法之二分查找法的实例详解 原理 假定查找范围为一个有序数组(如升序排列),要从中查找某一元素,如果该元素在此数组中,则返回其索引,否则返回-1.通过数组长度可取出中间位置元素的索引,将其值与 ...

  2. python bisect_Python实现二分查找与bisect模块详解

    前言 其实Python 的列表(list)内部实现是一个数组,也就是一个线性表.在列表中查找元素可以使用 list.index()方法,其时间复杂度为O(n) .对于大数据量,则可以用二分查找进行优化 ...

  3. 满满干货:二分查找/排序 编程题详解

    铁汁们~今天给大家分享一篇有关二分查找/排序 编程题详解(牛客网),满满干货,来吧,开造⛳️ 先给大家说些小知识点: 1.指针变量名[整数]=*(指针变量名+整数): 2.知识点:双指针 双指针指的是 ...

  4. 二分查找的魔鬼细节详解

    目录 二分查找的框架 基本二分查找--寻找一个数 寻找左侧边界的二分查找 寻找右侧边界的二分查找 二分查找的思想就是通过判断中间值与目标值的大小来逐步缩短目标区间 将大规模问题转换为若干个子问题,解在 ...

  5. 二分查找 归并排序 快排 详解C++

    这三个排序算法一直是面试的重点,大多数都是C语言写的,今天整理了一下C++的写法,思想都差不多.这几个排序经常忘记,今天抽空记在这,以便自己以后查阅,不对的地方,也欢迎大家评论,不吝指正,谢谢! 二分 ...

  6. linux shell 字符串操作(长度,查找,替换)详解 BASH

    linux shell 字符串操作(长度,查找,替换)详解 在做shell批处理程序时候,经常会涉及到字符串相关操作.有很多命令语句,如:awk,sed都可以做字符串各种操作. 其实shell内置一系 ...

  7. linux 查找目录或文件详解

    查找目录:find /(查找范围) -name '查找关键字' -type d 查找文件:find /(查找范围) -name 查找关键字 -print 如果需要更进一步的了解,可以参看Linux的命 ...

  8. 数据结构—2-3树、2-3-4树、B树、B+树等多路查找树的原理详解

    详细介绍了多路查找树中的2-3树.2-3-4树.B树.B+树的概念的区别,以及它们的应用场景. 文章目录 1 多路查找树的概述 1.1 索引概述 1.2 多路查找树的引出 2 2-3树 2.1 2-3 ...

  9. linux 查找目录或文件,linux 查找目录或文件详解

    查找目录:find /(查找范围) -name '查找关键字' -type d 查找文件:find /(查找范围) -name 查找关键字 -print 如果需要更进一步的了解,可以参看Linux的命 ...

最新文章

  1. webbrowser1 脚本报错_c# winform程序 webBrowser 当前页面的脚本发生异常 找不到成员...
  2. KDD Cup 2021 时序异常检测总结!
  3. 详解.Net中变量的命名和属性
  4. 在php中使用json
  5. 通过python实现卷积神经网络_Python 徒手实现 卷积神经网络 CNN
  6. java mysql实现原理_MySQL事务实现原理
  7. 10项技能让前端开发者价值百万!
  8. Poj 1936,3302 Subsequence(LCS)
  9. AT2 Homeomorphism and the group structure on a circle
  10. ORA-01078和LRM-00109问题导致ORACLE启动失败解决方法
  11. VB ListView控件各种操作详解
  12. Delphi FireMonkey 3D 编程初探
  13. 友盟分享微信图标显示成圆形
  14. 欧洲共同语言标准 c1,[转载]BEC,雅思等考试和欧洲共同语言参考标准的对照
  15. 免费服务器搭建--个人网站搭建第一步
  16. 利用Python将视频文件转成语音文件
  17. python uppercase函数_字符串-短rot13函数-Python
  18. 逻辑对计算机,对计算机模拟中的逻辑、方法论的几点认识
  19. Salesforce收购Slack背后的原因,你知道多少?
  20. 【每日早报】2019/08/08

热门文章

  1. 服务器连接显示18456,SQL2008无法连接到服务器,用户’XX’登录失败(错误18456)解决方法...
  2. SharePoint REST API contextinfo的使用
  3. 怎么除眼袋 苹果切片敷眼袋
  4. 数据字典阅读器PDMReader(生成数据字典的好助手)
  5. 状态提升(精读React官方文档—10)
  6. python中point什么意思_Python如何使用菲奥娜来确定这些多边形中的哪些点?,python,利用,fiona,判定,那些,point,在,polygon,内...
  7. 联想修复服务器系统还原,如何使用Windows恢复环境(Re)修复Windows 10系统
  8. LWN 翻译:Atomic Mode Setting 设计简介(上)
  9. 单播、组播、广播区别与联系
  10. 维修计算机需要理论知识吗,计算机维修工中级理论基础知识试卷.doc