商城首页欢迎来到中国正版软件门户

您的位置: 首页 > 文章列表 > 编程开发 > C#怎么使用BinarySearch查找_C#二分查找算法实现方法教程【技巧】

C#怎么使用BinarySearch查找_C#二分查找算法实现方法教程【技巧】

  发布于2026-07-18 阅读(0)

扫一扫,手机访问

BinarySearch 这个二分查找方法,在 C# 里可不是随便拿来就能用的——它要求数据必须已经升序排序,否则结果根本不可信。而且当目标值不存在时,它返回的不是常见的 -1,而是负数,这个负数的数学含义是“应插入位置的按位取反值”。这不是 bug,而是设计上的刻意安排,理解这一点才能真正用好它。

C#怎么使用BinarySearch查找_C#二分查找算法实现方法教程【技巧】

为什么 Array.BinarySearch 返回负数?

这是最容易被误解的地方。当你要找的值不存在时,Array.BinarySearch 返回的是 ~index,也就是插入位置的按位取反。比如返回 -4,意味着如果要把这个值放进去,应该放在索引 3 的位置(因为 ~3 == -4)。所以判断是否找到,必须用 result >= 0,而不是 result != -1——后者是很多新手掉进去的坑。如果没找到,想获取插入位置,用 ~result(但仅在 result < 0 时有效)。对于 List,要调用 list.BinarySearch(item),别用 list.FindIndex 或 LINQ 的 IndexOf,它们做的是线性扫描,不是二分。

BinarySearch 要求数组必须严格升序

这一点没有商量余地。哪怕只有一个逆序元素,比如 [1,3,2,4],结果都可能错乱——算法不会校验顺序,它只管按二分逻辑一路推进,顺序错了,逻辑就全歪了。升序是硬性前提,不是“建议”。如果数组是降序的,必须用自定义 IComparer,并且整个查找过程中比较器要保持一致,不能中途换。浮点数数组尤其要小心:double.NaN 会导致未定义行为,建议用 Comparer.Default 或者显式处理 NaN。字符串默认区分大小写,如果需要忽略大小写,记得传入 StringComparer.OrdinalIgnoreCase

泛型 List.BinarySearchArray.BinarySearch 的关键区别

两个 API 表面相似,但行为细节有差异,混用容易出错。Array.BinarySearch 有多个重载,支持从指定索引和长度范围进行查找;而 List.BinarySearch 没有等效的“子范围”参数,只能对整个列表操作。如果 ListBinarySearch 传入 nullT 是引用类型,会抛出 ArgumentNullException。另外,自定义比较器必须实现 IComparer,不能只写一个 Func 委托——后者需要包装成 Comparer.Create(...) 才能用。

性能陷阱:别在每次查找前排序

如果数据是动态变化的,而且查找频率很高,先 Sort()BinarySearch() 反而可能比线性扫描还慢。BinarySearch 的时间复杂度是 O(log n),但前提是数据已经排好序;排序本身是 O(n log n),单次查找完全划不来。高频读写场景,更推荐用 SortedSetSortedList,它们自动维护顺序,Contains 方法底层就是二分查找。如果只是偶尔查一次,数据量又小(比如小于几千),直接用 ContainsFirstOrDefault 更直观,也不容易出错。

真正用好 BinarySearch 的关键,是把“数据有序”当成一个契约来维护,而不是当成一次性的预处理步骤。一旦顺序被破坏,所有后续查找结果都失去意义——这一点比具体怎么写代码更难调试,但也是所有二分查找应用中最根本的教训。

本文转载于:https://www.php.cn/faq/2344291.html 如有侵犯,请联系zhengruancom@outlook.com删除。
免责声明:正软商城发布此文仅为传递信息,不代表正软商城认同其观点或证实其描述。

热门关注