在计算机科学中,排序算法是基础且关键的组成部分。它们负责将数据集按照特定的顺序排列,无论是升序还是降序。这些算法广泛应用于各种场景,从数据库管理到数据可视化,再到机器学习的数据预处理。今天,我们就来探讨一下十大经典排序方法的C#和Java实现,看看它们各自的特点和应用场景。
冒泡排序是一种简单直观的排序算法,它通过重复遍历列表,比较相邻元素并交换位置,直到列表完全有序。虽然冒泡排序不是最快的排序算法,但它易于理解和实现,适合小数据量排序。
C#:
using System;
class BubbleSort
{
public static void Main()
{
int[] arr = { 64, 34, 25, 12, 22, 11, 90 };
int n = arr.Length;
for (int i = 0; i < n - 1; i++)
{
for (int j = 0; j < n - i - 1; j++)
{
if (arr[j] > arr[j + 1])
{
int temp = arr[j];
arr[j] = arr[j + 1];
arr[j + 1] = temp;
}
}
}
Console.WriteLine("Sorted array:");
foreach (int element in arr)
{
Console.Write(element + " ");
}
}
}
Java:
public class BubbleSort {
public static void main(String[] args) {
int arr[] = {64, 34, 25, 12, 22, 11, 90};
int n = arr.length;
for (int i = 0; i < n - 1; i++) {
for (int j = 0; j < n - i - 1; j++) {
if (arr[j] > arr[j + 1]) {
int temp = arr[j];
arr[j] = arr[j + 1];
arr[j + 1] = temp;
}
}
}
System.out.println("Sorted array:");
for (int element : arr) {
System.out.print(element + " ");
}
}
}
接下来是插入排序,它类似于整理手中的扑克牌,每次将一个待排序的元素插入到已排序的序列中的适当位置。这种方法对小规模或部分有序的数据非常高效,但在大数据集中性能较差。
C#:
using System;
class InsertionSort
{
static void Main()
{
int[] arr = { 64, 34, 25, 12, 22, 11, 90 };
int n = arr.Length;
for (int i = 1; i < n; i++)
{
int key = arr[i];
int j = i - 1;
while (j >= 0 && arr[j] > key)
{
arr[j + 1] = arr[j];
j = j - 1;
}
arr[j + 1] = key;
}
Console.WriteLine("Sorted array:");
foreach (int element in arr)
{
Console.Write(element + " ");
}
}
}
Java:
public class InsertionSort {
public static void main(String[] args) {
int[] arr = {64, 34, 25, 12, 22, 11, 90};
int n = arr.length;
for (int i = 1; i < n; i++) {
int key = arr[i];
int j = i - 1;
while (j >= 0 && arr[j] > key) {
arr[j + 1] = arr[j];
j = j - 1;
}
arr[j + 1] = key;
}
System.out.println("Sorted array:");
for (int element : arr) {
System.out.print(element + " ");
}
}
}
选择排序则是一种更直接的方式,它会一次又一次地选择剩余元素中的最小值,并将其放在排序序列的末尾。这种方法容易实现,但效率并不高,因为它需要O(n^2)的时间复杂度。
C#:
using System;
class SelectionSort
{
static void Main()
{
int[] arr = { 64, 25, 12, 22, 11 };
int n = arr.Length;
for (int i = 0; i < n - 1; i++)
{
int min_idx = i;
for (int j = i + 1; j < n; j++)
{
if (arr[j] < arr[min_idx])
{
min_idx = j;
}
}
int temp = arr[min_idx];
arr[min_idx] = arr[i];
arr[i] = temp;
}
Console.WriteLine("Sorted array:");
foreach (int element in arr)
{
Console.Write(element + " ");
}
}
}
Java:
public class SelectionSort {
public static void main(String[] args) {
int arr[] = {64, 25, 12, 22, 11};
int n = arr.length;
for (int i = 0; i < n - 1; i++) {
int min_idx = i;
for (int j = i + 1; j < n; j++) {
if (arr[j] < arr[min_idx]) {
min_idx = j;
}
}
int temp = arr[min_idx];
arr[min_idx] = arr[i];
arr[i] = temp;
}
System.out.println("Sorted array:");
for (int element : arr) {
System.out.print(element + " ");
}
}
}
希尔排序是插入排序的一种改进版本,通过定义一个增量序列来确定元素比较的距离,使得即使在大数据集上也能保持较高的效率。
C#:
using System;
class ShellSort
{
static void Main()
{
int[] arr = {12, 34, 54, 2, 3};
int n = arr.Length;
for (int gap = n / 2; gap > 0; gap /= 2)
{
for (int i = gap; i < n; i++)
{
int temp = arr[i];
int j;
for (j = i; j >= gap && arr[j - gap] > temp; j -= gap)
{
arr[j] = arr[j - gap];
}
arr[j] = temp;
}
}
Console.WriteLine("Sorted array:");
foreach (int element in arr)
{
Console.Write(element + " ");
}
}
}
Java:
public class ShellSort {
public static void main(String[] args) {
int[] arr = {12, 34, 54, 2, 3};
int n = arr.length;
for (int gap = n / 2; gap > 0; gap /= 2) {
for (int i = gap; i < n; i++) {
int temp = arr[i];
int j;
for (j = i; j >= gap && arr[j - gap] > temp; j -= gap) {
arr[j] = arr[j - gap];
}
arr[j] = temp;
}
}
System.out.println("Sorted array:");
for (int element : arr) {
System.out.print(element + " ");
}
}
}
归并排序采用分治策略,将数据集分割成小块,分别排序后再合并。它是一种稳定的、非原地排序算法,时间复杂度为O(n log n)。
C#:
using System;
class MergeSort
{
static void Main()
{
int[] arr = {12, 11, 13, 5, 6, 7};
MergeSortFunction(arr, 0, arr.Length - 1);
Console.WriteLine("Sorted array:");
foreach (int element in arr)
{
Console.Write(element + " ");
}
}
static void MergeSortFunction(int[] arr, int l, int r)
{
if (l < r)
{
int m = l + (r - l) / 2;
MergeSortFunction(arr, l, m);
MergeSortFunction(arr, m + 1, r);
Merge(arr, l, m, r);
}
}
static void Merge(int[] arr, int l, int m, int r)
{
int n1 = m - l + 1;
int n2 = r - m;
int[] L = new int[n1];
int[] R = new int[n2];
for (int i = 0; i < n1; i++)
L[i] = arr[l + i];
for (int j = 0; j < n2; j++)
R[j] = arr[m + 1 + j];
int k = l, x = 0, y = 0;
while (x < n1 && y < n2)
{
if (L[x] <= R[y])
{
arr[k] = L[x];
x++;
}
else
{
arr[k] = R[y];
y++;
}
k++;
}
while (x < n1)
arr[k++] = L[x++];
while (y < n2)
arr[k++] = R[y++];
}
}
Java:
public class MergeSort {
public static void main(String[] args) {
int[] arr = {12, 11, 13, 5, 6, 7};
mergeSort(arr, 0, arr.length - 1);
System.out.println("Sorted array:");
for (int element : arr) {
System.out.print(element + " ");
}
}
static void mergeSort(int[] arr, int l, int r){
if (l < r) {
int m = l + (r - l) / 2;
mergeSort(arr, l, m);
mergeSort(arr, m + 1, r);
merge(arr, l, m, r);
}
}
static void merge(int[] arr, int l, int m, int r){
int n1 = m - l + 1;
int n2 = r - m;
int[] L = new int[n1];
int[] R = new int[n2];
for (int i = 0; i < n1; i++)
L[i] = arr[l + i];
for (int j = 0; j < n2; j++)
R[j] = arr[m + 1 + j];
int i = 0, j = 0;
int k = l;
while (i < n1 && j < n2){
if (L[i] <= R[j]){
arr[k] = L[i];
i++;
}
else{
arr[k] = R[j];
j++;
}
k++;
}
while (i < n1){
arr[k] = L[i];
i++;
k++;
}
while (j < n2){
arr[k] = R[j];
j++;
k++;
}
}
}
快速排序同样使用分治思想,选择一个基准值,然后将数组分为小于和大于基准值的两个子数组,递归地对这两个子数组进行排序。尽管最坏情况下的时间复杂度为O(n^2),但平均情况下它是非常高效的。
C#:
using System;
class QuickSort
{
static void Main()
{
int[] arr = { 12, 11, 13, 5, 6, 7 };
QuickSortFunction(arr, 0, arr.Length - 1);
Console.WriteLine("Sorted array:");
foreach (int element in arr)
{
Console.Write(element + " ");
}
}
static void QuickSortFunction(int[] arr, int low, int high)
{
if (low < high)
{
int pi = Partition(arr, low, high);
QuickSortFunction(arr, low, pi - 1);
QuickSortFunction(arr, pi + 1, high);
}
}
static int Partition(int[] arr, int low, int high)
{
int pivot = arr[high];
int i = low - 1;
for (int j = low; j <= high - 1; j++)
{
if (arr[j] < pivot)
{
i++;
int temp = arr[i];
arr[i] = arr[j];
arr[j] = temp;
}
}
int temp1 = arr[i + 1];
arr[i + 1] = arr[high];
arr[high] = temp1;
return i + 1;
}
}
Java:
public class QuickSort {
public static void main(String[] args) {
int[] arr = {12, 11, 13, 5, 6, 7};
quickSort(arr, 0, arr.length - 1);
System.out.println("Sorted array:");
for (int element : arr) {
System.out.print(element + " ");
}
}
static void quickSort(int[] arr, int low, int high){
if (low < high) {
int pi = partition(arr, low, high);
quickSort(arr, low, pi - 1);
quickSort(arr, pi + 1, high);
}
}
static int partition(int[] arr, int low, int high){
int pivot = arr[high];
int i = low - 1;
for (int j = low; j < high; j
堆排序利用二叉堆这一数据结构的特性,可以迅速找到最大或最小的元素。它是一种原地、非稳定的排序算法,时间复杂度为O(n log n)。
C#:
using System;
class HeapSort
{
static void Main()
{
int[] arr = {12, 11, 13, 5, 6, 7};
HeapSortFunction(arr);
Console.WriteLine("Sorted array:");
foreach (int element in arr)
{
Console.Write(element + " ");
}
}
static void HeapSortFunction(int[] arr)
{
int n = arr.Length;
for (int i = n / 2 - 1; i >= 0; i--)
Heapify(arr, n, i);
for (int i = n - 1; i > 0; i--)
{
int temp = arr[0];
arr[0] = arr[i];
arr[i] = temp;
Heapify(arr, i, 0);
}
}
static void Heapify(int[] arr, int n, int i)
{
int largest = i;
int left = 2 * i + 1;
int right = 2 * i + 2;
if (left < n && arr[left] > arr[largest])
largest = left;
if (right < n && arr[right] > arr[largest])
largest = right;
if (largest != i)
{
int swap = arr[i];
arr[i] = arr[largest];
arr[largest] = swap;
Heapify(arr, n, largest);
}
}
}
Java:
public class HeapSort {
public static void main(String[] args) {
int[] arr = {12, 11, 13, 5, 6, 7};
heapSort(arr);
System.out.println("Sorted array:");
for (int element : arr) {
System.out.print(element + " ");
}
}
static void heapSort(int[] arr){
int n = arr.length;
for (int i = n / 2 - 1; i >= 0; i--)
heapify(arr, n, i);
for (int i = n - 1; i > 0; i--){
int temp = arr[0];
arr[0] = arr[i];
arr[i] = temp;
heap
计数排序是一个线性时间复杂度的排序算法,适用于知道最大数值和最小数值的情况。它通过创建一个计数数组来记录每个元素的出现次数,然后根据这个信息重新构建排序后的数组。
C#:
using System;
class CountingSort
{
static void Main()
{
int[] arr = {4, 2, 2, 8, 3, 3, 1};
CountingSortFunction(arr);
Console.WriteLine("Sorted array:");
foreach (int element in arr)
{
Console.Write(element + " ");
}
}
static void CountingSortFunction(int[] arr)
{
int n = arr.Length;
int max = arr[0];
for (int i = 1; i < n; i++)
{
if (arr[i] > max)
max = arr[i];
}
int[] count = new int[max + 1];
int[] output = new int[n];
for (int i = 0; i < n; i++)
{
count[arr[i]]++;
}
for (int i = 1; i <= max; i++)
{
count[i] += count[i - 1];
}
for (int i = n - 1; i >= 0; i--)
{
output[count[arr[i]] - 1] = arr[i];
count[arr[i]]--;
}
for (int i = 0; i < n; i++)
{
arr[i] = output[i];
}
}
}
Java:
public class CountingSort {
public static void main(String[] args) {
int[] arr = {4, 2, 2, 8, 3, 3, 1};
countingSort(arr);
System.out.println("Sorted array:");
for (int element : arr) {
System.out.print(element + " ");
}
}
static void countingSort(int[] arr) {
int n = arr.length;
int max = arr[0];
for (int i = 1; i < n; i++) {
if (arr[i] > max)
max = arr[i];
}
int[] count = new int[max + 1];
int[] output = new int[n];
for (int i = 0; i < n; i++) {
count[arr[i]]++;
}
for (int i = 1;
桶排序与计数排序类似,都是线性时间复杂度的排序算法。它将元素分布到有限数量的桶中,每个桶各自排序,然后连接各个桶。适用于元素均匀分布在特定范围的场景。
C#:
using System;
using System.Collections.Generic;
using System.Linq;
class BucketSort
{
static void Main()
{
int[] arr = {170, 45, 75, 90, 802, 24, 2, 66};
List<int> sortedArr = BucketSortFunction(arr);
Console.WriteLine("Sorted array:");
foreach (int element in sortedArr)
{
Console.Write(element + " ");
}
}
static List<int> BucketSortFunction(int[] arr)
{
int n = arr.Length;
List<int> sortedArr = new List<int>();
List<int>[] buckets = new List<int>[n];
for (int i = 0; i < n; i++)
{
int bucket = arr[i] / 10;
if (buckets[bucket] == null)
{
buckets[bucket] = new List<int>();
}
buckets[bucket].Add(arr[i]);
}
for (int i = 0; i < n; i++)
{
if (buckets[i] != null)
{
buckets[i] = buckets[i].OrderBy(x => x).ToList();
sortedArr.AddRange(buckets[i]);
}
}
return sortedArr;
}
}
Java:
import java.util.ArrayList;
import java.util.List;
public class BucketSort {
public static void main(String[] args) {
int[] arr = {170, 45, 75, 90, 802, 24, 2, 66};
List<Integer> sortedArr = bucketSort(arr);
System.out.println("Sorted array:");
for (int element : sortedArr) {
System.out.print(element + " ");
}
}
static List<Integer> bucketSort(int[] arr) {
int n = arr.length;
List<Integer> sortedArr = new ArrayList<>();
List<Integer>[] buckets = new List[n];
for (int i = 0; i < n; i++) {
int bucket = arr[i] / 10;
if (buckets[bucket] == null) {
buckets[bucket] = new ArrayList<>();
}
buckets[bucket].add(arr[i]);
}
for (int i = 0; i < n; i++) {
if (
基数排序是一种基于数字的位或基数的排序方法,它使用稳定的子过程(如计数排序)按位进行排序。由于其稳定性,基数排序特别适合对大型数字集合进行排序。
C#:
using System;
class RadixSort
{
static void Main()
{
int[] arr = {170, 45, 75, 90, 802, 24, 2, 66};
int n = arr.Length;
int max = arr[0];
for (int i = 1; i < n; i++)
{
if (arr[i] > max)
max = arr[i];
}
for (int exp = 1; max / exp > 0; exp *= 10)
CountingSort(arr, n, exp);
Console.WriteLine("Sorted array:");
foreach (int element in arr)
{
Console.Write(element + " ");
}
}
static void CountingSort(int[] arr, int n, int exp)
{
int[] output = new int[n];
int[] count = new int[10];
for (int i = 0; i < n; i++)
count[(arr[i] / exp) % 10]++;
for (int i = 1; i < 10; i++)
count[i] += count[i - 1];
for (int i = n - 1; i >= 0; i--)
{
output[count[(arr[i] / exp) % 10] - 1] = arr[i];
count[(arr[i] / exp) % 10]--;
}
for (int i = 0; i < n; i++)
arr[i] = output[i];
}
}
Java:
public class RadixSort {
public static void main(String[] args) {
int[] arr = {170, 45, 75, 90, 802, 24, 2, 66};
int n = arr.length;
int max = arr[0];
for (int i = 1; i < n; i++) {
if (arr[i] > max) {
max = arr[i];
}
}
for (int exp = 1; max / exp > 0; exp *= 10) {
countingSort(arr, n, exp);
}
System.out.println("Sorted array:");
for (int element : arr) {
System
在实现这些算法时,C#和Java都有各自的特点。C#提供了丰富的库函数,使得实现某些算法更加简便。而Java则以其跨平台的特性和强大的社区支持而备受青睐。不过,无论选择哪种语言,理解每种排序算法的原理和适用场景都是编程中不可或缺的技能。
声明:所有来源为“聚合数据”的内容信息,未经本网许可,不得转载!如对内容有异议或投诉,请与我们联系。邮箱:marketing@think-land.com
支持识别各类商场、超市及药店的购物小票,包括店名、单号、总金额、消费时间、明细商品名称、单价、数量、金额等信息,可用于商品售卖信息统计、购物中心用户积分兑换及企业内部报销等场景
涉农贷款地址识别,支持对私和对公两种方式。输入地址的行政区划越完整,识别准确度越高。
根据给定的手机号、姓名、身份证、人像图片核验是否一致
通过企业关键词查询企业涉讼详情,如裁判文书、开庭公告、执行公告、失信公告、案件流程等等。
IP反查域名是通过IP查询相关联的域名信息的功能,它提供IP地址历史上绑定过的域名信息。