C# 中的排序

PHPz
發布: 2024-09-03 15:24:11
原創
432 人瀏覽過

C#中的排序是將集合中的內容依特定順序排列的過程。集合可以是數組、列表或任何其他資料組。此集合可能包含簡單類型和複雜類型的元素。簡單類型可以是整數、字串、浮點數等的集合。複雜類型可以是使用者定義類型的物件的集合,例如 Employee、Student 等。複雜類型通常是嵌套的,這意味著物件可能有多個屬性。

範例

  • 簡單型
    • 整數集合 – {1, 2, 3, 4, 5}
    • 字串集合 – {「Mark」、「Jamie」、「Anna」}
  • 複雜型
    • { [姓名:“Mark”,員工 ID:“123”,辦公室:“倫敦”],
      [姓名:“Jane”,員工 ID:“456”,辦公室:“NY”],
      [姓名:“Annie”,員工 ID:“789”,辦公室:“雪梨”] }

C# 提供了內建方法來對集合進行排序。無論是陣列、列表或任何通用集合,C# Sort() 方法都可以根據提供的比較器對其進行排序。在內部,.Net 實作使用快速排序演算法對 C# 中的集合進行排序。我們將在本文的後續部分中對此進行更多討論。

C# 中如何進行排序?

如前所述,.Net 框架使用快速排序方法對 C# 集合中的元素進行排序。那麼,什麼是快速排序?

快速排序遵循分而治之的策略。這意味著,排序演算法選擇一個主元元素並根據主元元素劃分數組。小於樞軸的元素放置在其前方。大於樞軸的元素放置在其後面。這確保了主元元素已排序。此外,陣列被分成兩部分-小於主元的元素和大於主元的元素。接下來,該演算法對兩個陣列都遵循相同的方法。

下面是一個範例。

未排序數組 – 18, 5, 16, 23, 50, 32

第 1 步(樞軸 = 32)– 18、5、16、23、32、50

步驟 2a
未排序數組 – 18、5、16、23
樞軸 = 23
部分排序數組 – 18, 5, 16, 23

步驟 2b
未排序數組 – 50
樞軸 = 50
部分排序數組 – 50

步驟 3a
未排序數組 – 18、5、16
樞軸 = 16
部分排序數組 – 5, 16, 18

排序數組 – 5、16、18、23、32、50

因此,快速排序有兩個關鍵過程-選擇樞軸和分割陣列。演算法的實作取決於主元的選擇。它可以是第一個元素,也可以是最後一個元素,也可以是任意隨機元素,也可以是陣列的中位數。一旦分區完成並且樞軸被放置在正確的位置,演算法就會被遞歸地呼叫分區數組,直到每個元素都被排序。

在C#中進行排序時,就出現了穩定快速排序和不穩定快速排序的概念。在穩定的快速排序中,如果兩個元素相等,則它們在原始數組中的順序將被保留。否則,它就處於不穩定的快速排序中。 C# 實作使用不穩定的快速排序。

C# 中的排序類型

在本文的這一部分,我們將主要關注 C# 中的兩種類型的集合 - 陣列和列表。我們將深入研究 C# 如何對陣列和清單進行排序。下一節將嘗試用一些例子來解釋它。

1.在 C# 中對陣列進行排序

讓我們看看在 C# 中對陣列進行排序的不同方式。

a.使用預設比較器

這是預設的 Sort() 方法。如果沒有明確地將 Comparer 傳遞給該方法,C# 將使用升序排列元素。

代碼:

using System;
public class Program
{
public static void Main()
{
String[] strArray = {"I", "Am", "Learning", "Array", "Sorting","In", "C#"};
int[] intArray = {23, 76, 12, 43, 90, 30};
Array.Sort(strArray);
Array.Sort(intArray);
Console.WriteLine("Sorted String Array:\n");
DisplayArray(strArray);
Console.WriteLine("\n\n\nSorted Integer Array:\n");
DisplayArray(intArray);
}
static void DisplayArray(string[] arr)
{
foreach (string a in arr)
{
Console.Write(a + "\t");
}
}
static void DisplayArray(int[] arr)
{
foreach (int a in arr)
{
Console.Write(a + "\t");
}
}
}
登入後複製

輸出:

C# 中的排序

b.使用自訂比較器

我們也可以為 Sort() 方法提供我們自己的自訂比較器。這將指示 C# 編譯器使用自訂比較器而不是預設比較器。

要建立自訂比較器,我們需要從 IComparer 介面實作 Compare() 方法。下面的程式碼示範如何建立一個比較器,以降序對元素進行排序。

我們創建了一個類,繼承自 IComparer 接口,實現了 Compare() 方法並重寫它以按降序比較元素。

代碼:

using System;
public class DescendingComparer : System.Collections.IComparer
{
public int Compare(Object a, Object b)
{
return (new System.Collections.CaseInsensitiveComparer()).Compare(b, a);
}
}
public class Program
{
public static void Main()
{
String[] strArray = {"I", "Am", "Learning", "Array", "Sorting","In", "C#"};
int[] intArray = {23, 76, 12, 43, 90, 30};
Array.Sort(strArray, new DescendingComparer());
Array.Sort(intArray, new DescendingComparer());
Console.WriteLine("Sorted String Array in Descending Order:\n");
DisplayArray(strArray);
Console.WriteLine("\n\n\nSorted Integer Array in Desc Order:\n");
DisplayArray(intArray);
}
static void DisplayArray(string[] arr)
{
foreach (string a in arr)
{
Console.Write(a + "\t");
}
}
static void DisplayArray(int[] arr)
{
foreach (int a in arr)
{
Console.Write(a + "\t");
}
}
}
登入後複製

輸出:

C# 中的排序

c. Using Key-Value Pairs

C# also provides a way to sort one array using key values from another array. The example below has key-value pairs of first names and last names of people. We would sort them by both first and last names using the Sort() method.

Code:

using System;
public class Program
{
public static void Main()
{
String[] firstNames = {"Tom", "Jack", "Anna", "Veronica", "Jessica", "Mike"};
String[] lastNames = {"Phelps", "Anderson", "Spectre", "Clarke",   "Williams", "Fonseca"};
Array.Sort(firstNames, lastNames);
Console.WriteLine("Sorted by First Names:\n");
DisplayArray(firstNames, lastNames);
Array.Sort(lastNames, firstNames);
Console.WriteLine("\n\nSorted by Last Names:\n");
DisplayArray(firstNames, lastNames);
}
static void DisplayArray(string[] arr1, string[] arr2)
{
for (int i = 0; i < arr1.Length; i++)
{
Console.WriteLine(arr1[i] + " " + arr2[i]);
}
}
}
登入後複製

Output:

C# 中的排序

2. Sorting a List in C#

Let us look at the different ways in which we can sort a list in C#.

Note – To use Lists in C#, including the library System.Collections.Generic.
a. Using Default Comparer

This is the default sort() method. if no comparer is explicitly passed to the method, c# uses the ascending order to arrange the elements.

Code:

public class Program
using System.Collections.Generic;
{
public static void Main()
{
String[] strArray = {"I", "Am", "Learning", "Array", "Sorting", "In", "C#"};
List<string> strList = new List<string>(strArray);
int[] intArray = {23, 76, 12, 43, 90, 30};
List<int> intList = new List<int>(intArray);
strList.Sort();
intList.Sort();
Console.WriteLine("Sorted String List:\n");
DisplayList(strList);
Console.WriteLine("\n\n\nSorted Integer List:\n");
DisplayList(intList);
}
static void DisplayList(List<string> myList)
{
foreach (string a in myList)
{
Console.Write(a + "\t");
}
}
static void DisplayList(List<int> myList)
{
foreach (int a in myList)
{
Console.Write(a + "\t");
}
}
}
登入後複製

Output:

C# 中的排序

b. Using Custom Comparer

We can also provide our own custom comparer to the sort() method. This would instruct the c# compiler to use the custom comparer instead of the default one.

To create a custom comparer, we need to implement the Compare() method from the IComparer interface. The code below demonstrates how to create a comparer that would sort the elements in descending order.

We created a class, inherited it from the IComparer interface, implemented the Compare() method and overrode it to compare the elements in descending order.

Code:

using System;
using System.Collections.Generic;
public class LengthComparer : IComparer<string>
{
public int Compare(string a, string b)
{
return (a.Length.CompareTo(b.Length));
}
}
public class DigitSumComparer : IComparer<int>
{
public int Compare(int a, int b)
{
int sum_a = 0;
int sum_b = 0;
while (a > 0)
{
sum_a += (a % 10);
a /= 10;
}
while (b > 0)
{
sum_b += (b % 10);
b /= 10;
}
return (sum_a.CompareTo(sum_b));
}
}
public class Program
{
public static void Main()
{
LengthComparer lc = new LengthComparer();
DigitSumComparer dsc = new DigitSumComparer();
String[] strArray = {"I", "Am", "Learning", "Array", "Sorting", "In", "C#"};
List<string> strList = new List<string>(strArray);
int[] intArray = {23, 76, 12, 43, 90, 30};
List<int> intList = new List<int>(intArray);
strList.Sort(lc);
intList.Sort(dsc);
Console.WriteLine("Sorted String List by Length:\n");
DisplayList(strList);
Console.WriteLine("\n\n\nSorted Integer List by Sum of Digits:\n");
DisplayList(intList);
}
static void DisplayList(List<string> myList)
{
foreach (string a in myList)
{
Console.Write(a + "\t");
}
}
static void DisplayList(List<int> myList)
{
foreach (int a in myList)
{
Console.Write(a + "\t");
}
}
}
登入後複製

Output:

C# 中的排序

Sorting Complex List Types

Complex List Types are user-defined lists. To be more precise, they are lists of objects of user-defined classes. Being user-defined, the objects are a mixture of various primitive types. It is difficult to sort a complex list type. C# compiler expects each complex class to inherit from the IComparable interface and define the method CompareTo(). This method contains the instructions on how to compare the elements of the list for sorting.

In the example below, we define a user-defined class of Employees and sort the Employee objects based on their IDs.

Example #1

Code:

using System;
using System.Collections.Generic;
public class Employee : IComparable<Employee>
{
public int id {get;set;}
public string name{get;set;}
public double salary{get;set;}
public int CompareTo(Employee e)
{
return this.id.CompareTo(e.id);
}
}
public class Program
{
public static void Main()
{
List<Employee> emps = new List<Employee>();
emps.Add(new Employee()
{id = 123, name = "Tom Phelps", salary = 20000.00});
emps.Add(new Employee()
{id = 897, name = "Jack Anderson", salary = 40050.50});
emps.Add(new Employee()
{id = 342, name = "Anna Spectre", salary = 31030.89});
emps.Add(new Employee()
{id = 219, name = "Veronica Clarke", salary = 66333.66});
emps.Add(new Employee()
{id = 642, name = "Jessica Williams", salary = 50505.05});
emps.Add(new Employee()
{id = 923, name = "Mike Fonseca", salary = 76543.21});
Console.WriteLine("Original Employee List:\n");
DisplayList(emps);
emps.Sort();
Console.WriteLine("\n\nSorted Employee List by IDs:\n");
DisplayList(emps);
}
static void DisplayList(List<Employee> emp)
{
foreach (Employee e in emp)
{
Console.WriteLine("Id: " + e.id + ", Name: " + e.name + ",  Salary: " + e.salary);
}
}
}
登入後複製

Output:

 C# 中的排序

Now, the obvious question that comes to mind is that what if we want to sort the objects of Employee class based on some other property? This is possible. We would need to implement the IComparer interface. Let us take a look at the example below to understand.

Example #2

Code:

using System;
using System.Collections.Generic;
public class Employee
{
public int id {get;set;}
public string name{get;set;}
public double salary{get;set;}
}
public class SortByName : IComparer<Employee>
{
public int Compare(Employee e1, Employee e2)
{
return e1.name.CompareTo(e2.name);
}
}
public class SortBySalary : IComparer<Employee>
{
public int Compare(Employee e1, Employee e2)
{
return e1.salary.CompareTo(e2.salary);
}
}
public class Program
{
public static void Main()
{
SortByName sbn = new SortByName();
SortBySalary sbs = new SortBySalary();
List<Employee> emps = new List<Employee>();
emps.Add(new Employee()
{id = 123, name = "Tom Phelps", salary = 20000.00});
emps.Add(new Employee()
{id = 897, name = "Jack Anderson", salary = 40050.50});
emps.Add(new Employee()
{id = 342, name = "Anna Spectre", salary = 31030.89});
emps.Add(new Employee()
{id = 219, name = "Veronica Clarke", salary = 66333.66});
emps.Add(new Employee()
{id = 642, name = "Jessica Williams", salary = 50505.05});
emps.Add(new Employee()
{id = 923, name = "Mike Fonseca", salary = 76543.21});
emps.Sort(sbn);
Console.WriteLine("Sorted Employee List by Names:\n");
DisplayList(emps);
emps.Sort(sbs);
Console.WriteLine("\n\nSorted Employee List by Salaries:\n");
DisplayList(emps);
}
static void DisplayList(List<Employee> emp)
{
foreach (Employee e in emp)
{
Console.WriteLine("Id: " + e.id + ", Name: " + e.name + ",  Salary: " + e.salary);
}
}
}
登入後複製

Output:

C# 中的排序

Conclusion

So, this article covered in-depth on how to sort collections in C#. We focused majorly on Arrays and Lists since these two covers all the primitive types as well. Once the concept of Sorting in C# is very well understood, it becomes easy to implement sorting in other collections such as Enumerations, Dictionaries, etc. After completing this article, it is recommended to explore the MSDN documentation for more implementations of Sorting in C#.

以上是C# 中的排序的詳細內容。更多資訊請關注PHP中文網其他相關文章!

相關標籤:
來源:php
本網站聲明
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn
熱門教學
更多>
最新下載
更多>
網站特效
網站源碼
網站素材
前端模板