C# 常用排序算法实现与解析
本文将深入探讨C#语言中常用的几种基础排序算法,包括冒泡排序、选择排序、插入排序、希尔排序以及快速排序。文章不仅展示了每种算法的逻辑原理,还提供了可直接运行的C#代码实现,涵盖从简单重复比较到递归分治的不同技术路径,旨在帮助开发者清晰理解各类排序机制的特点与应用。
结果或目标
在软件开发中,数据排序是处理信息的核心操作之一。不同的排序算法在时间复杂度、空间复杂度以及稳定性上各有差异。对于C#开发者而言,理解底层排序逻辑有助于在特定场景下做出更优的性能选择。本文将依次介绍五种经典排序算法的实现方法。
准备条件
为了运行以下示例代码,您需要具备以下环境:
- 开发环境:安装 Visual Studio 或其他支持 C# 的 IDE(如 VS Code配合 .NET SDK)。
- 运行环境.NET Runtime 支持执行标准的 Console Application。
- 基础知识:了解 C# 的基本语法、数组操作、循环结构与递归概念。
真实操作顺序:五种排序算法实现
第1步:实现冒泡排序 (Bubble Sort)
目的:通过相邻元素的反复比较与交换,将最大元素逐步“浮”到数组末尾。这是一种最基础的稳定排序算法,但效率较低。
参数:int[] list 待排序整数数组。
代码实现
using System;
namespace BubbleSorter
{
public class BubbleSorter
{
public void Sort(int [] list)
{
int i, j, temp;
bool done = false;
j = 1;
// 外层循环控制趟数
while ((j < list.Length) && (!done))
{
done = true; // 假设本轮无需交换
for (i = 0; i < list.Length - j; i++)
{
// 如果前一个元素大于后一个,则交换
if (list[i] > list[i+1])
{
done = false;
temp = list[i];
list[i] = list[i+1];
list[i+1] = temp;
}
}
j++;
}
}
}
public class MainClass
{
public static void Main()
{
int[] iArrary = new int[]{1,5,13,6,10,55,99,2,87,12,34,75,33,47};
BubbleSorter sh = new BubbleSorter();
sh.Sort(iArrary);
for (int m = 0; m < iArrary.Length; m++)
{
Console.Write("{0} ", iArrary[m]);
}
Console.WriteLine();
}
}
}
第2步:实现选择排序 (Selection Sort)
目的:每次从未排序部分中找到最小元素,将其放到已排序部分的末尾。属于不稳定排序,比较次数固定,但交换次数较少。
参数:int[] list 待排序整数数组。
代码实现
using System;
namespace SelectionSorter
{
public class SelectionSorter
{
private int min;
public void Sort(int [] list)
{
// 遍历未排序区间的每一个位置
for (int i = 0; i < list.Length - 1; i++)
{
min = i; // 假设当前位置是最小值索引
// 在未排序区间中寻找真正的最小值
for (int j = i + 1; j < list.Length; j++)
{
if (list[j] < list[min])
min = j;
}
// 将找到的最小值与当前无序区第一个元素交换
int t = list[min];
list[min] = list[i];
list[i] = t;
}
}
}
public class MainClass
{
public static void Main()
{
int[] iArrary = new int[]{1,5,3,6,10,55,9,2,87,12,34,75,33,47};
SelectionSorter ss = new SelectionSorter();
ss.Sort(iArrary);
for (int m = 0; m < iArrary.Length; m++)
{
Console.Write("{0} ", iArrary[m]);
}
Console.WriteLine();
}
}
}
第3步:实现插入排序 (Insertion Sort)
目的:构建有序序列,对于未排序数据,在已排序序列中从后向前扫描,找到相应位置并插入。对基本有序的数据集非常高效。
参数:int[] list 待排序整数数组。
代码实现
using System;
namespace InsertionSorter
{
public class InsertionSorter
{
public void Sort(int [] list)
{
// 从第二个元素开始,逐个插入到前面已排序的部分
for (int i = 1; i < list.Length; i++)
{
int t = list[i]; // 暂存当前要插入的元素
int j = i;
// 在已排序部分从后往前找位置
while ((j > 0) && (list[j-1] > t))
{
list[j] = list[j-1]; // 向后移动元素
--j;
}
list[j] = t; // 插入正确位置
}
}
}
public class MainClass
{
public static void Main()
{
int[] iArrary = new int[]{1,13,3,6,10,55,98,2,87,12,34,75,33,47};
InsertionSorter ii = new InsertionSorter();
ii.Sort(iArrary);
for (int m = 0; m < iArrary.Length; m++)
{
Console.Write("{0}", iArrary[m]);
}
Console.WriteLine();
}
}
}
第4步:实现希尔排序 (Shell Sort)
目的:插入排序的改进版。通过将整个待排序元素序列分割成若干子序列分别进行直接插入排序,待整个序列中的元素“基本有序”时,再对全体元素进行一次直接插入排序。缩小增量是核心思想。
参数:int[] list 待排序整数数组。
代码实现
using System;
namespace ShellSorter
{
public class ShellSorter
{
public void Sort(int [] list)
{
int inc;
// 计算初始增量 gap
for (inc = 1; inc <= list.Length/9; inc = 3*inc+1);
// 逐步缩小增量进行排序
for (; inc > 0; inc /= 3)
{
for (int i = inc+1; i <= list.Length; i += inc)
{
int t = list[i-1];
int j = i;
// 在增量子序列中进行插入操作
while ((j > inc) && (list[j-inc-1] > t))
{
list[j-1] = list[j-inc-1];
j -= inc;
}
list[j-1] = t;
}
}
}
}
public class MainClass
{
public static void Main()
{
int[] iArrary = new int[]{1,5,13,6,10,55,99,2,87,12,34,75,33,47};
ShellSorter sh = new ShellSorter();
sh.Sort(iArrary);
for (int m = 0; m < iArrary.Length; m++)
{
Console.Write("{0} ", iArrary[m]);
}
Console.WriteLine();
}
}
}
第5步:实现快速排序 (Quick Sort)
目的:采用分治法策略。选择一个基准元素(Pivot),将数组分为两部分:一部分比基准小,另一部分比基准大。然后递归地对两部分进行排序。平均时间复杂度为 O(n log n),是同数量级中最快的排序方法之一,但不稳定。
参数:int[] arr 待排序数组,low 低端索引,high 高端索引。
代码实现
using System;
using System.Collections.Generic;
using System.Text;
namespace SoloDataStructure
{
class MyQuickSort
{
/// <summary>
/// 划分数组,返回中心轴记录位置
/// </summary>
static int Partition(int[] arr, int low, int high)
{
int pivot = arr[low]; // 把中心轴置于arr[low]
while (low < high)
{
// 从右向左找小于pivot的元素
while(low<high && arr[high]>=pivot)
--high;
Swap(ref arr[high], ref arr[low]);
// 从左向右找大于pivot的元素
while(low<high && arr[low]<=pivot)
++low;
Swap(ref arr[high], ref arr[low]);
}
arr[low] = pivot; // 中心轴移到正确位置
return low; // 返回中心轴位置
}
static void Swap(ref int i, ref int j)
{
int t;
t = i;
i = j;
j = t;
}
static void QuickSort(int[] arr, int low, int high)
{
if (low < high-1) // 当区间为空或只一个记录无需排序
{
int pivot = Partition(arr, low, high);
QuickSort(arr, low, pivot-1); // 递归排序左半部分
QuickSort(arr, pivot+1, high); // 递归排序右半部分
}
}
static void Main(string[] args)
{
int[] arr = new int[]{54,62,99,14,28,1,8,77,99,3,110};
QuickSort(arr, 0, arr.Length-1);
Console.Write("Data After QuickSort:");
foreach (int i in arr)
{
Console.Write(i+",");
}
Console.ReadLine();
}
}
}
完成判断
您可以复制上述任意一段代码到 C# 项目中编译运行。若控制台输出了按升序排列的数字序列(例如冒泡排序输出 1 2 5 ... 99,快速排序输出 1,3,8,...,110,),则表明排序算法逻辑正确且已生效。
简要总结
冒泡、选择和插入排序适合小规模或近似有序的数据,实现简单但效率随数据量增长下降较快;希尔排序通过跳跃式比较优化了插入排序;快速排序凭借优秀的平均性能成为通用排序的首选。在实际业务开发中,建议优先使用框架内置的 Array.Sort(),但在面试或算法学习场景中,掌握上述手动实现至关重要。
以上就是C#多种排序算法实现的详细内容,更多关于C#算法教程的资料请关注本站其它相关文章!
免责声明:本文内容仅供参考,不代表本站观点。转载或引用请注明出处。









