C# | 二分查找算法的实现

news2024/12/23 0:10:37

C# | 二分查找算法的实现

文章目录

  • C# | 二分查找算法的实现
    • 前言
    • 示例代码
    • 算法思路
    • 测试结果
    • 结束语

前言

二分查找法一种在有序数组中查找目标值的算法。划重点——“有序”,与需要遍历整个数组的查询算法不同,二分查找法通过将数组分成两部分来快速定位目标值所在的位置。

  • 二分查找法有什么用呢?
    它的主要好处在于它的效率很高。因为它能够通过每次排除一半的元素来快速缩小搜索范围,因此在大型数据集上使用二分查找法可以显著提高查找速度。

  • 比较一下二分查找法和其他常见的查找算法的效率。
    相比于顺序查找法,它的平均时间复杂度更低,可以达到O(log n)。而对于哈希表查找法,虽然哈希表可以在O(1)的时间内查找目标值,但是哈希表需要额外的空间来存储哈希函数和冲突处理,而且哈希表在处理数据集较小的情况下效率不如二分查找法。

示例代码

现在来看一下C#中的二分查找算法是如何实现的:

        /// <summary>
        /// 二分法查找目标值在数组中的索引(值的比较由回调完成,不提供目标值)
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="array">数据集合</param>
        /// <param name="comparer">比较回调</param>
        /// <param name="strategy">匹配策略,如果是完全匹配策略,则若没有相等的则返回-1,若策略是匹配不到时采用较小值,则返回最接近的前一个值,若策略是匹配不到时采用较大值,则返回最接近的后一个值</param>
        /// <returns></returns>
        public static int BinarySearch<T>(T[] array, Func<T, ComparisonResult> comparer, MatchStrategy strategy)
        {
            int left = 0;
            int right = array.Length - 1;
            int result = -1;

            while (left <= right)
            {
                int mid = left + (right - left) / 2;
                ComparisonResult comparison = comparer(array[mid]);

                if (comparison == ComparisonResult.Equal)
                {
                    result = mid;
                    break;
                }
                else if (comparison == ComparisonResult.Less)
                {
                    left = mid + 1;
                }
                else
                {
                    right = mid - 1;
                }
            }

            if (result != -1)
            {
                return result;
            }
            else if (strategy == MatchStrategy.ExactMatch)
            {
                return -1;
            }
            else if (strategy == MatchStrategy.LowerBound)
            {
                if (right < 0)
                {
                    return -1;
                }
                else
                {
                    return right;
                }
            }
            else // strategy == MatchStrategy.UpperBound
            {
                if (left >= array.Length)
                {
                    return -1;
                }
                else
                {
                    return left;
                }
            }
        }
        

这段代码实现了一个泛型的二分查找法,可以适用于任何数据类型。通过传递一个比较回调函数和一个匹配策略,我们可以在数组中查找目标值的索引。

补充一下,关于示例中使用到的ComparisonResult枚举类型和MatchStrategy枚举类型的源代码如下:

    public enum ComparisonResult
    {
        Less = -1,
        Equal = 0,
        Greater = 1,
    }

    public enum MatchStrategy
    {
        ExactMatch,
        LowerBound,
        UpperBound
    }

算法思路

  1. 定义了左右两个指针,分别指向数组的头和尾。
  2. 不断将数组分成两半,直到找到目标值为止。在每一次迭代中,我们通过计算中间值来判断目标值在左半边还是右半边。如果目标值等于中间值,那么我们就找到了目标值的索引。如果目标值小于中间值,那么我们就在左半边继续查找。如果目标值大于中间值,那么我们就在右半边继续查找。
  3. 根据匹配策略返回目标值的索引或者最接近目标值的索引。

测试结果

测试代码如下:

        /// <summary>
        /// 测试BinarySearch方法在数组中查找一个存在的元素时能够正确返回其索引值。
        /// </summary>
        [TestMethod]
        public void TestBinarySearch_ExistingElement_ReturnsCorrectIndex()
        {
            // Arrange
            int[] array = { 1, 3, 5, 7, 9 };
            Func<int, ComparisonResult> comparer = x => x.CompareTo(5) switch
            {
                -1 => ComparisonResult.Less,
                0 => ComparisonResult.Equal,
                _ => ComparisonResult.Greater
            };
            MatchStrategy strategy = MatchStrategy.ExactMatch;

            // Act
            int result = Dichotomy.BinarySearch(array, comparer, strategy);

            // Assert
            Assert.AreEqual(2, result);
        }

执行结果如下:
在这里插入图片描述

结束语

通过本章的代码可以轻松实现二分查找算法。如果您觉得本文对您有所帮助,请不要吝啬您的点赞和评论,提供宝贵的反馈和建议,让更多的读者受益。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/609908.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

MATLAB-二维图形的绘制

本博文主要介绍绘图函数 Plot 函数的使用,图形的网格、坐标、标题、图例备注以及线型和颜色标记等。 一、Plot 指令 将数据绘制成曲线的函数是 Plot 指令, 该命令可以带有不同数目的参数。最简单的形式就是将数据传递给 Plot , 但是线条的类型和颜色和颜色…

Vue.js 比较重要知识点总结三

概述 Vue 中 nextTick 的实现原理v-if 和 v-show 的区别Vue 中的 key 有什么作用如何理解ref toRef和toRefsComposition API如何实现代码逻辑复用&#xff1f; Vue 中 nextTick 的实现原理 在下次 DOM 更新循环结束之后执行延迟回调。在修改数据之后立即使用这个方法&#xf…

chatgpt赋能python:Python在线聊天:实现即时通讯的快速解决方案

Python在线聊天&#xff1a;实现即时通讯的快速解决方案 在当今数字时代&#xff0c;在线聊天已经成为人与人之间交流的主流方式。Python在线聊天应用程序提供了一种快速且可定制的解决方案&#xff0c;使个人用户和企业可以进行互联网通信。本文将向您介绍Python在线聊天的基…

软考A计划-电子商务设计师-电子商务系统建设

点击跳转专栏>Unity3D特效百例点击跳转专栏>案例项目实战源码点击跳转专栏>游戏脚本-辅助自动化点击跳转专栏>Android控件全解手册点击跳转专栏>Scratch编程案例 &#x1f449;关于作者 专注于Android/Unity和各种游戏开发技巧&#xff0c;以及各种资源分享&am…

深挖MYSQL大表加索引

深挖MYSQL大表加索引 起因是这样的&#xff0c;有一张表存在慢sql&#xff0c;查询耗时最多达到12s&#xff0c;定位问题后发现是由于全表扫描导致&#xff0c;需要对字段增加索引&#xff0c;但是表的数据量600多万有些大&#xff0c;网上很多都说对大表增加索引可能会导致锁…

垂直行业(新站)SEO流量快速起飞的核心思路

现在做站不比以前了&#xff0c;不管你是做百度也好&#xff0c;还是谷歌也罢&#xff0c;对于行业精准SEO流量来说肯定是没有以前那么容易做了。但是不容易做不代表没有机会做&#xff0c;机会一直还是有的&#xff0c;尤其是最近百度打击泛站&#xff0c;对于垂直行业来说其实…

chatgpt赋能python:Python图片尺寸大小修改指南

Python图片尺寸大小修改指南 在现代网站设计中&#xff0c;图像是非常重要的一部分。图片质量和大小是网站排名和用户体验的关键因素。一般来说&#xff0c;网站应该尽量避免使用过多的大图片&#xff0c;因为它们会使用户等待过长的时间&#xff0c;同时也会降低网站的加载速…

JAVA基础练习(6)

目录 1.冒泡排列学员成绩(降序) 2.常用Arrays类的应用 2.1.sort 2.2.equals 2.3.toString 2.4.fill 2.5.Arrays.copyOf 2.6.binarySearch 3.利用二维数组计算成绩 1.冒泡排列学员成绩(降序) package ch06;import java.util.Arrays; import java.util…

代码随想录算法训练营第四十一天|343. 整数拆分|96.不同的二叉搜索树

LeetCode343. 整数拆分 动态规划五部曲&#xff1a; 1&#xff0c;确定dp数组&#xff08;dp table&#xff09;以及下标的含义&#xff1a;dp[i]&#xff1a;分拆数字i&#xff0c;可以得到的最大乘积为dp[i]。 2&#xff0c;确定递推公式&#xff1a;可以想 dp[i]最大乘积…

下载安装微软office的详细步骤

目录 一、前言 二、下载路径 &#xff08;一&#xff09;wps office 办公软件下载地址 1.wps office办公软件下载地址 &#xff08;二&#xff09;微软office 办公软件下载地址--2021 1.专业增强版 2.专业版 3.家庭专业版 4.家庭企业版 &#xff08;三&#xff09;…

JAVA基础练习(1)

目录 1.练习一:使用变量存储数据&#xff0c;实现个人简历信息的输出 2.练习二:使用Scanner类获取键盘输入的会员卡号&#xff0c;并将该数据存储在变量中&#xff0c;输出这个变量的信息 3.练习三:键盘输入四位数字的会员卡号,使用“/”和“%”运算符分解获得会员卡各个位上…

(二)模拟实现 《资源发现》框架

文章目录 前言资源发现《资源发现》概述技术难点 《资源发现》基本思想《资源发现》框架思考需求分析技术选择 《资源发现》技术难点实现《资源发现》框架实现资源发现基础类实现资源注册中心的实现资源持有者和资源请求者资源持有者和资源请求者功能具体实现 前言 《资源发现…

JAVA基础练习(4)

目录 1.利用循环打印九九乘法表 2.使用循环输出 100、95、90、85.......5 3.输入星期查看对应结果 4.几行数字展示 5.打印1-100之间13的倍数&#xff0c;使用for循环 6.用*来打印&#xff0c;根据用户输入rows和columns&#xff0c;来打印响应矩形 7.输入三个班&#xff…

YOLO8自定义检测实战

文章目录 资料模型介绍(或者叫weights)安装安装ultralytics&#xff08;yolo&#xff09;Torch测试命令 CLI命令行通过COCO128数据集体验yolov8标签predictsegment下载COCO 2017数据集ValTrain 自定义数据集标注标注软件labelimg分析训练结果 获得最佳训练结果提示 资料 Docs:…

docker学习记录

1.什么是docker&#xff1f; Docker是一个容器引擎&#xff0c;使用 Linux 内核功能&#xff08;如命名空间和控制组&#xff09;在操作系统之上创建容器。除了作为一种容器技术之外&#xff0c;Docker 还具有定义明确的包装器组件&#xff0c;这使打包应用程序变得十分容易&am…

Windows认证机制

windows认证基础 windows的认证包括三个部分&#xff1a; 本地认证&#xff1a;用户直接操作计算机登录账户网络认证&#xff1a;远程连接到工作组中的某个设备域认证&#xff1a;登录到域环境中的某个设备 本地认证 1、用户输入密码 2、系统收到密码后将用户输入的密码计…

LeetCode 周赛 348(2023/06/05)数位 DP 模板学会了吗

本文已收录到 AndroidFamily&#xff0c;技术和职场问题&#xff0c;请关注公众号 [彭旭锐] 加入知识星球提问&#xff01; 往期回顾&#xff1a;LeetCode 单周赛第 347 场 二维空间上的 LIS 最长递增子序列问题 周赛 348 概览 T1. 最小化字符串长度&#xff08;Medium&…

chatgpt赋能python:Python基础教程:如何利用Python进行地区查询

Python基础教程&#xff1a;如何利用Python进行地区查询 在现代社会&#xff0c;人们越来越关注自己所处的地理位置和周边环境。这就导致了地区查询变得越来越流行&#xff0c;因为它可以让人们更加方便地获取自己想要的信息。 Python作为一门强大的编程语言&#xff0c;不仅…

chatgpt赋能python:Python在线模拟:提高编程技能的必备工具

Python在线模拟&#xff1a;提高编程技能的必备工具 Python是一种广泛应用于各行业的编程语言&#xff0c;也是许多工程师的选择。成为一名Python工程师意味着拥有高薪、稳定的职业和无尽的机会。但是如何成为一名高效的Python工程师&#xff1f;在线模拟器做到了提高技能和编…

Servlet与Mabatis-1

Web 应用开发 get 和 post 请求方法 &#xff08;重点&#xff09; http 协议中定义的请求方法有 DELETE、HEAD、GET、OPTIONS、POST、PUT、TRACE 在 http 协议中的两种常见的传参方法 get/post&#xff0c;例如 get 和 post 的共同点&#xff1a;Get 提交和 post 提交都是…