博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
数据结构和算法之——二分查找下
阅读量:5876 次
发布时间:2019-06-19

本文共 3217 字,大约阅读时间需要 10 分钟。

最简单的二分查找情况下,我们假设数组中没有重复元素,因此很容易实现。如果数组中存在重复元素,二分查找就没有想象中那么容易了。

1. 查找第一个值等于给定值的元素?

如果数据中存在相同的元素,但我们要查找第一个值等于给定值的元素,如果直接用最简单的二分查找,显然是不满足的。

看下面的例子,有 3 个等于 8 的元素,简单二分查找会返回 7,但第一个值等于 8 的元素应该是 a[5]。

其实,只要我们在简单二分查找的基础上再多加上一点限制即可。

当我们发现 a[mid] = val 时,我们需要继续确认 a[mid] 左边还有没有等于 val 的元素。若 mid 左边没有和 a[mid] 相等的元素,则此时 a[mid] 就是我们要找的第一个值等于给定值的元素。另外,若 mid 到了第一个元素的位置,说明左边已经没有元素,此时 a[mid] 也即是我们要找的元素。否则,我们就需要继续向左边查找。

float Binary_Search(float data[], int left, int right, float value){    int begin = left;    while (left <= right)    {        int mid = left + (right - left) / 2;        if (value == data[mid])        {            if (mid == begin || a[mid - 1] != a[mid]) return mid;            else right = mid - 1;        }        else if (value < data[mid])        {            right = mid - 1;        }        else        {            left = mid + 1;        }    }    return -1;}

2. 查找最后一个值等于给定值的元素?

这个问题和上面要查找第一个值等于给定值的问题思路一样,只不过是查找的方向改变了。

当我们发现 a[mid] = val 时,我们需要继续确认 a[mid] 右边还有没有等于 val 的元素。若 mid 右边没有和 a[mid] 相等的元素,则此时 a[mid] 就是我们要找的最后一个值等于给定值的元素。另外,若 mid 到达了最后一个元素的位置,说明右边已经没有元素,此时 a[mid] 也即是我们要找的元素。否则,我们就需要继续向右边查找。

float Binary_Search(float data[], int left, int right, float value){    int end = right;    while (left <= right)    {        int mid = left + (right - left) / 2;        if (value == data[mid])        {            if (mid == end || a[mid + 1] != a[mid]) return mid;            else left = mid + 1;        }        else if (value < data[mid])        {            right = mid - 1;        }        else        {            left = mid + 1;        }    }    return -1;}

3. 查找第一个大于等于给定值的元素?

当我们发现 a[mid] >= val 时,我们需要继续确认 a[mid] 左边还有没有大于等于 val 的元素。若 mid 左边的值小于 a[mid],则此时 a[mid] 就是我们要找的第一个大于等于给定值的元素。另外,若 mid 到达了第一个元素的位置,说明左边已经没有元素,此时 a[mid] 也即是我们要找的元素。否则,我们就需要继续向左边查找。

float Binary_Search(float data[], int left, int right, float value){    int begin = left;    while (left <= right)    {        int mid = left + (right - left) / 2;        if (data[mid] >= value)        {            if (mid == begin || a[mid - 1] < a[mid]) return mid;            else right = mid - 1;        }        else        {            left = mid + 1;        }          }    return -1;}

4. 查找最后一个小于等于给定值的元素?

当我们发现 a[mid] <= val 时,我们需要继续确认 a[mid] 右边还有没有小于等于 val 的元素。若 mid 右边的值大于 a[mid],则此时 a[mid] 就是我们要找的最后一个小于等于给定值的元素。另外,若 mid 到达了最后一个元素的位置,说明右边已经没有元素,此时 a[mid] 也即是我们要找的元素。否则,我们就需要继续向右边查找。

float Binary_Search(float data[], int left, int right, float value){    int end = right;    while (left <= right)    {        int mid = left + (right - left) / 2;        if (data[mid] <= value)        {            if (mid == end || a[mid + 1] > a[mid]) return mid;            else left = mid + 1;        }        else        {            right = mid - 1;        }          }    return -1;}

5. 如何快速定位 IP 对应的省份?

当我们要查找 202.102.133.13 这个 IP 地址的归属地时,我们就在地址库中搜索,发现这个 IP 位于 [202.102.133.0, 202.102.133.255] 这个范围内,我们就可以找到对应的归属地——山东东营。

[202.102.133.0, 202.102.133.255]  山东东营市 [202.102.135.0, 202.102.136.255]  山东烟台 [202.102.156.34, 202.102.157.255] 山东青岛 [202.102.48.0, 202.102.48.255] 江苏宿迁 [202.102.49.15, 202.102.51.251] 江苏泰州 [202.102.56.0, 202.102.56.255] 江苏连云港

因此,我们可以按照 IP 地址库的起始地址对所有区间进行排序,然后问题就转化为了找到最后一个起始地址小于等于给定 IP 地址的区间

获取更多精彩,请关注「seniusen」!

转载地址:http://dikix.baihongyu.com/

你可能感兴趣的文章
老叶观点:MySQL开发规范之我见
查看>>
阿里云重磅推出物联网安全运营中心Link SOC
查看>>
CDN WAF功能开放公测 提升网络应用安全性能
查看>>
oracle学习笔记-第一篇
查看>>
redis演练(2) 最全redis命令列表
查看>>
不要猜,要测试!Code Tools: jmh
查看>>
python模块-part2
查看>>
Nginx 安装配置 禁止使用IP访问 rewrite重写 别名设置 日志轮询
查看>>
PowerShell天天学——01
查看>>
Linux下DNS实战篇之主从同步
查看>>
centos7 安装之后 TAB无法自动补全 !?
查看>>
MFC标签页--对话框
查看>>
我的友情链接
查看>>
mysql主从+keepalived高可用
查看>>
11g rac ORA-01157问题处理
查看>>
国内code平台托管开源站点
查看>>
U盘的常见物理故障类型和故障表现汇总
查看>>
生产线上的nginx如何添加未编译安装模块
查看>>
面向过程与函数式编程区别的浅显理解
查看>>
你人生中的那口井挖了没有?
查看>>