C#怎么获取数组中第二大的数_C#如何编写巧妙的排序逻辑【技巧】

穿越時空

穿越時空

2026-03-29

583人浏览

原创

获取数组中第二大的唯一值应使用distinct().orderbydescending(x=>x).skip(1).firstordefault(),兼顾去重、降序、空安全与简洁性。

c#怎么获取数组中第二大的数_c#如何编写巧妙的排序逻辑【技巧】

OrderByDescending + Skip + First 最快写出来

多数人第一反应是排序再取索引 1,但直接调用 OrderByDescending 会新建数组、触发完整排序——其实只要第二大的值,没必要全排完。LINQ 的 Skip(1).First() 组合能少做不少事,尤其对大数组更明显。

常见错误现象:arr.OrderBy(x => x).Skip(arr.Length - 2).First() 写反方向,结果拿到倒数第二小;或没处理重复值,比如 {5,5,4,3,2} 里第二大的其实是 4,不是 5。

  • 必须用 OrderByDescending,不是 OrderBy
  • 重复值要跳过:先 Distinct(),再 Skip(1).First()
  • 数组长度不足 2 时会抛 InvalidOperationException,得提前检查

示例:

var secondLargest = arr.Distinct().OrderByDescending(x => x).Skip(1).FirstOrDefault();
注意用了 FirstOrDefault 而非 First,避免空序列崩溃。

不用 LINQ 时怎么手写一次遍历

如果项目禁用 LINQ、或对性能极度敏感(比如嵌入式场景),就得手动扫一遍。核心思路是维护两个变量:largestsecondLargest,边扫边更新——时间复杂度 O(n),空间 O(1),且天然去重。

容易踩的坑:secondLargest 初始值设成 int.MinValue 看似合理,但遇到全是负数且最大值就是 int.MinValue 时会出错;还有人把更新逻辑写成“如果比 largest 小就更新 second”,漏掉了“比 largest 小但比 current second 大”的分支。

  • 初始化用 long.MinValue 或直接用数组前两元素推导,别硬写死最小值
  • 更新顺序很重要:先更新 secondLargest(当值介于两者之间),再更新 largest(当值更大)
  • 遇到相等值直接跳过,不参与比较

示例关键片段:

long largest = Math.Max(arr[0], arr[1]);<br>long secondLargest = Math.Min(arr[0], arr[1]);<br>for (int i = 2; i   if (arr[i] > largest) {<br>    secondLargest = largest;<br>    largest = arr[i];<br>  } else if (arr[i] > secondLargest && arr[i]     secondLargest = arr[i];<br>  }<br>}

Array.Sort 后取索引 1 的隐患

有人图省事直接 Array.Sort(arr, (a,b) => b.CompareTo(a)); return arr[1];,看起来短,但有三个硬伤:破坏原数组、没去重、没边界保护。

C函数速查手册(CHM版)
C函数速查手册(CHM版)

C函数速查手册(CHM版)

下载

使用场景受限:只适合临时数组、且确认长度 ≥ 2、且允许修改原数据。一旦 arr 是别人传来的引用,或者后续还要用原始顺序,这就埋了雷。

  • Array.Sort 是 in-place 排序,原数组顺序永久丢失
  • 重复最大值(如 {9,9,8,7})会导致 arr[1] 还是 9,不是想要的 8
  • 若数组只有 1 个元素,arr[1] 直接 IndexOutOfRangeException

真要用排序法,至少得:

var copy = (int[])arr.Clone();<br>Array.Sort(copy, (a,b) => b.CompareTo(a));<br>var distinctCopy = copy.Distinct().ToArray();<br>return distinctCopy.Length > 1 ? distinctCopy[1] : throw new InvalidOperationException();
但这就绕回 LINQ 了,不如第一步直接用。

泛型数组和 null 值怎么处理

如果数组元素是 int? 或自定义类,Distinct 和比较逻辑会变脆弱。比如 null 参与比较会抛异常,OrderByDescending 默认把 null 排最前(升序)或最后(降序),但语义上“第二大”不该包含 null

参数差异明显:值类型数组(int[])可直接比;引用类型必须提供 IComparer<t></t> 或用 CompareTo 显式判空;Nullable 类型得先 Where(x => x.HasValue) 过滤。

  • int? 数组,先 .Where(x => x.HasValue).Select(x => x.Value) 再走主逻辑
  • 自定义类必须实现 IComparable,否则 OrderByDescendingArgumentException
  • Comparer<t>.Default</t> 比手写 lambda 更安全,尤其涉及 null 时

示例过滤 null:

var validNumbers = arr.Where(x => x != null).Cast<int>().Distinct();</int>
注意 Cast<int>()</int> 仅适用于非 null 元素,否则运行时报错。

实际写的时候,绝大多数情况用第一种 LINQ 写法足够清晰可靠。真正卡性能或不能引用 System.Linq 的时候,才值得花精力手写单次遍历——但那个逻辑里“更新 second 的条件判断顺序”和“初始值选取”,多看两遍代码才能确保没漏 case。

相关专题

更多
c#是什么意思
c#是什么意思

C#是一种通用的面向对象编程语言,它在.NET框架上运行,可用于开发各种类型的应用程序。本专题为大家提供c#相关的各种文章、以及下载和课程。

2023.08.08

528

5

什么是c#
什么是c#

C#(读作C Sharp)是一种现代的、通用的、面向对象的编程语言。它由微软公司开发,于2000年首次发布,主要用于开发Windows桌面应用程序、Web应用程序、移动应用程序以及游戏开发等领域。C#是一种类型安全和托管的编程语言,它结合了C++的强大性能和C语言的简单易学特点,并引入了许多新的特性和概念,如委托、属性、泛型和异步编程等,以提高开发效率和代码可维护性。

2023.08.31

1158

3

C#中base关键字的用法
C#中base关键字的用法

在C#中,base关键字用于访问当前类的基类成员,这包括基类的字段、属性、方法、构造函数、索引器以及事件。想了解更多C#的相关内容,可以阅读本专题下面的文章。

2024.03.13

556

8

C#Task用法
C#Task用法

Task在C#中是用于表示异步操作的对象,它位于System.Threading.Tasks命名空间中。想了解更多C#中各种用法的相关内容,可以阅读本专题下面的文章。

2024.03.14

1051

11

C# 并发与异步编程
C# 并发与异步编程

本专题系统讲解 C# 异步编程与并发控制,重点介绍 async 和 await 关键字、Task 类、线程池管理、并发数据结构、死锁与线程安全问题。通过多个实战项目,帮助学习者掌握 如何在 C# 中编写高效的异步代码,提升应用的并发性能与响应速度。

2026.02.03

148

18

C# 多线程与异步编程
C# 多线程与异步编程

本专题深入讲解 C# 中多线程与异步编程的核心概念与实战技巧,包括线程池管理、Task 类的使用、async/await 异步编程模式、并发控制与线程同步、死锁与竞态条件的解决方案。通过实际项目,帮助开发者掌握 如何在 C# 中构建高并发、低延迟的异步系统,提升应用性能和响应速度。

2026.02.06

202

20

C# ASP.NET Core微服务架构与API网关实践
C# ASP.NET Core微服务架构与API网关实践

本专题围绕 C# 在现代后端架构中的微服务实践展开,系统讲解基于 ASP.NET Core 构建可扩展服务体系的核心方法。内容涵盖服务拆分策略、RESTful API 设计、服务间通信、API 网关统一入口管理以及服务治理机制。通过真实项目案例,帮助开发者掌握构建高可用微服务系统的关键技术,提高系统的可扩展性与维护效率。

2026.03.11

526

24

C# Unity游戏开发与ECS架构实践
C# Unity游戏开发与ECS架构实践

本专题聚焦 C# 在 Unity 游戏开发中的应用,系统讲解 ECS(Entity-Component-System)架构设计、游戏对象管理、性能优化与内存控制策略。通过实际游戏案例,帮助开发者构建高性能、结构清晰的游戏系统,提高游戏开发效率与运行性能。

2026.04.13

137

20

页面置换算法
页面置换算法

页面置换算法是操作系统中用来决定在内存中哪些页面应该被换出以便为新的页面提供空间的算法。本专题为大家提供页面置换算法的相关文章,大家可以免费体验。

2023.08.14

2422

4

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
RabbitMQ 教程手册
RabbitMQ 教程手册

共0课时 | 0人学习

Linux man-pages 项目
Linux man-pages 项目

共0课时 | 0人学习

C# 教程
C# 教程

共94课时 | 20.2万人学习