C# 中以降序排序数组的不同方法

2024年8月29日 | 阅读 10 分钟

排序是将元素按特定顺序排列的基本过程。它在计算机科学和数学中都有应用。排序的主要目的是使元素搜索更容易、按特定顺序访问它们以及执行依赖于已排序数据的有效算法。一些常见的排序顺序如下。

升序

元素按升序排列,即从小到大。

降序

在这种顺序中,元素按**降序**排列,即从**大到小**。

在 C# 中,可以使用**各种方法**将数组按降序排序。

一、Array.Sort 方法与自定义比较器

C# 中的 **Array.sort** 方法是一个内置方法,用于对数组元素进行排序。当您想按降序对数组进行排序时,请使用 **Array.Sort** 方法和自定义比较器。自定义比较器是一个定义元素比较规则的对象。

语法

它具有以下语法:

参数

  • **数组:**它是需要排序的元素数组。
  • **比较:**一个委托,表示用于比较元素的方法。它接受两个 T 类型的参数并返回一个整数。
  • 第一个元素的负值应排在第二个元素之前。
  • **零**表示元素在排序方面被视为相等。
  • 第一个元素的正值应排在第二个元素之后。

示例

让我们看一个例子,说明如何在 C# 中使用 **Array.Sort()** 方法将数组按降序排序。

输出

Sorted Array in Descending order: 
37 24 16 12 4

说明

1. 数组声明

在此示例中,我们定义了一个要按降序排序的数字数组。

2. Sort 方法

对数组调用 **Array.sort** 方法,我们使用 lambda 表达式提供一个自定义比较器。

lambda 表达式 **(a, b) => b.CompareTo(a)** 定义了一个比较函数,该函数比较两个元素(a 和 b),以便排序将按降序进行。

**b.CompareTo(a) 函数**产生降序排序,确保 b 在排序顺序中排在 a 之前。

3. 获取已排序数组以显示

之后,使用 **foreach** 循环显示排序后的数组。

在此示例中,Array.Sort 方法使用 lambda 表达式给出的自定义比较器对数组进行降序排序。lambda 表达式指定了比较逻辑,这确保了所有元素都按所需顺序放置。

二、使用 LINQ 的 OrderBy 和 ToArray

  • **LINQ(Language-Integrated Query)**提供了一种用于查询集合的声明性语法。
  • **OrderByDescending** 方法根据指定的键按降序对元素进行排序。
  • **ToArray** 方法将结果转换为新数组。
  • 在 C# 中对数组进行排序的一种简单且富有表现力的方法是使用 LINQ 的 OrderBy 和 ToArray 函数。

OrderBy 方法

C# 提供了包含 OrderBy 方法的**语言集成查询 (LINQ)** 扩展方法。给定一个键,它将序列元素按升序排序。**OrderByDescending** 也可用于按降序排序元素。

ToArray 方法

使用 **ToArray** 方法将 **LINQ 查询**结果转换为数组。如果您希望将 LINQ 查询结果转换为数组,这将很有帮助。

示例

让我们看一个例子,说明如何在 C# 中使用 **LINQ 的 OrderBy** 和 **ToArray** 函数将数组按降序排序。

输出

Sorted Array in Descending Order:
47 44 32 28 16

说明

1. 命名空间导入

在此示例中,代码包含必要的命名空间。System 提供基本类和基类型,而 System.Linq 提供 **LINQ(语言集成查询)** 功能。

2. 数组初始化

声明并初始化一个名为 **'numbers'** 的整数值数组。

3. 使用 LINQ 排序

使用 **OrderByDescending LINQ 方法**对数组进行降序排序。

为了确定如何提取排序键,使用 lambda 表达式 num => num 作为键选择器。在这种情况下,根据整数值进行排序使其成为一个简单的恒等函数。

结果被分配给变量 **sorted_Array**。

4. 转换为数组

之后,使用 **ToArray** 函数将 **LINQ 查询**结果转换为新数组。

排序后的数组现在存储在 **sorted_Array 变量**中。

5. 显示排序后的数组。

显示一条消息,显示数组的降序排序。

使用 **foreach 循环**遍历 **sorted_Array** 中的每个元素。

控制台打印每个元素,**之间有一个空格**。

三、使用 Array.Sort 和自定义比较委托

表示具有特定参数列表和返回类型的方法引用的类型称为**委托**。**Comparison ** 委托表示比较两个对象的方法,可在排序上下文中使用。

C# 中的 Array.Sort 方法允许您提供自定义比较委托进行排序。

语法

它具有以下语法:

  • **delegate:**delegate 关键字用于声明委托类型。委托类型表示对具有特定签名的方法的引用。
  • **int:**它指定方法的返回类型。在这种情况下,方法应返回一个 int。
  • **ComparisonDelegate:**委托类型称为 **ComparisonDelegate**。它可以在使用时与许多提供的类型一起使用,因为它是一个泛型委托。**ComparisonDelegate** 是泛型的,T 是一个类型参数,如尖括号 **()** 所示。它允许委托与不同类型一起使用,而无需在委托声明中直接指定类型。
  • ** (T x, T y):** 这些是委托方法的参数。在这种情况下,委托表示的方法接受两个参数 **(x 和 y)**,两者都是 T 类型。**'T'** 是在委托级别指定的类型参数,使委托灵活且可用于各种类型。

示例

让我们看一个例子,说明如何在 C# 中使用 **Array.Sort** 和**自定义比较委托**函数将数组按降序排序。

输出

Sorted Array in Descending Order:
60 54 51 37 21

说明

1. 命名空间导入

代码首先使用 **using System** 导入 System 命名空间,其中包含基类和基本类型。

2. 自定义委托声明

**ComparisonDelegate** 是声明的自定义委托的名称。此泛型委托的目的是表示返回 int 并比较两个 T 类型值的方法。

3. Main 方法

程序的入口点是 Main 方法。

4. 数组初始化

初始化一个名为 **num_bers** 的整数数组,其值为 **{54, 21, 60, 51, 37}**。

5. 使用 Array.Sort 排序

使用 **Array.Sort** 方法对 **num_bers** 数组进行排序。

使用 new Comparison **((a, b) => b.CompareTo(a))** 创建一个委托实例。此委托表示一个自定义比较方法,该方法以相反顺序比较两个整数,从而实现降序排序。

6. 显示结果

程序在控制台打印消息 **"Sorted Array in Descending Order:"**。

使用 foreach 循环遍历排序后的**数组 (num_bers)** 的每个元素并将其打印到控制台。

四、List 和 Sort 方法

在 C# 中,**List** 类是 **System.Collections.Generic** 命名空间的一部分,它提供了一个动态数组式数据结构,可以动态调整大小。使用 **List 类**的 Sort 方法对列表中的元素进行排序。

List

1. 动态数组

动态数组由泛型集合类 List 表示。它无需固定大小即可动态添加、删除和访问元素。

2. 类型安全

List 的泛型特性确保了**类型安全**,因为它可以存储**特定类型 (T)** 的元素。

3. 调整大小

为了提供灵活性并消除手动内存管理的需要,**List** 在添加或删除元素时会调整其大小。

Sort 方法

1. 就地排序

**List ** 类的 Sort 方法执行就地排序,这意味着它直接在现有 List 中重新排列元素,而无需创建新列表。

2. 比较委托

Sort 方法可以使用类型 T 的默认比较器,也可以接受 **Comparison** 委托来确定元素的顺序。

3. 性能

Sort 使用的排序算法是一种自适应的混合算法,对于各种输入数据都表现良好。

4. 复杂性

Sort 方法对于大型列表是有效的,因为它的平均时间复杂度为 **O(n log n)**。

示例

让我们看一个例子,说明如何在 C# 中使用 **List** 和 **Sort 方法**将数组按降序排序。

输出

Sorted List (Descending Order):
64 53 49 37 29

说明

1. Using 指令

程序开头的 using 指令指示正在使用的命名空间。在此示例中,使用了 System 和 **System.Collections.Generic**。

2. 类声明 - Demo

在代码中定义了一个名为 **Demo** 的类。这是 C# 程序**开始**的地方。

3. Main 方法

程序的执行从 Main 方法开始。它首先创建一个名为 **num_bers** 的列表,并用以下值初始化它:**53、37、64、29** 和 **49**。

4. 列表降序排序

使用 **List 类**的 Sort 函数,可以通过提供自定义**比较函数 (a, b) => b.CompareTo(a)** 来将 List 的成员按降序排序,排序以降序进行。此 lambda 表达式使用 **CompareTo** 方法比较项目 a 和 b,该方法用于自然排序。

5. 显示排序后的列表

之后,程序使用 **foreach** 循环以递减顺序打印排序后的 List。排序后的 List 的所有元素都打印到控制台。

总而言之,该程序初始化一个整数列表,使用 Sort 函数和自定义比较对 List 进行降序排序,然后将排序后的 List 打印到控制台。

五、升序排序后反转

对数组进行降序排序可以通过先将其升序排序,然后反转它来执行。当使用的编程语言或库默认支持升序排序时,这是一种常用的方法。

1. 升序排序

将元素按特定顺序排列称为**排序**。数组的元素按升序排序时,从小到大重新排列。

2. 反转顺序

反转顺序涉及在数组按升序排序后,将元素从数组末尾移动到开头。

3. 结果 - 降序

当先按升序排序,然后反转顺序时,数组按降序排序。

现在,元素从大到小排序。

示例

让我们再举一个例子,说明如何在 C# 中按**降序**对数组进行排序。

输出

Sorted and Reversed Numbers:
8 5 3 2 1

说明

1. 数组初始化

在名为 **num_bers** 的数组中定义并初始化五个整数值:**5、2、8、1** 和 **3**。

2. 升序排序

使用 **Array.Sort** 方法对 **num_bers** 数组的元素进行升序排序。

3. 反转顺序

之后,应用 **Array.Reverse** 方法反转排序数组的顺序。这意味着最初按升序排列的元素现在按降序排列。

4. 显示结果

最后,在控制台显示 **"Sorted and Reversed Numbers"**。

使用 **foreach** 循环遍历 **num_bers 数组**的元素。

打印每个元素到终端后,打印一个空格。