C# 排序算法之计数排序

计数排序(Counting Sort)是一种非比较型整数排序算法,其核心在于将输入的数据值转化为键存储在额外开辟的数组空间中。作为一种线性时间复杂度的排序,它要求输入的数据必须是有确定范围的整数。

以下是计数排序算法的C#实现:

using System;

class Program
{
    static void Main(string[] args)
    {
        int[] arr = { 4, 2, 2, 8, 3, 3, 1 };

        // 调用计数排序
        CountingSort(arr);

        Console.WriteLine("Sorted array: ");
        foreach (int num in arr)
        {
            Console.Write(num + " ");
        }
        Console.WriteLine();
    }

    // 计数排序方法
    static void CountingSort(int[] arr)
    {
        if (arr.Length == 0)
            return;

        // 找到数组中的最大值,以确定计数数组的大小
        int max = arr[0];
        for (int i = 1; i < arr.Length; i++)
        {
            if (arr[i] > max)
                max = arr[i];
        }

        // 创建计数数组,并初始化为0
        // 计数数组的大小为最大值+1,因为数组索引是从0开始的
        int[] count = new int[max + 1];

        // 计算每个元素的出现次数
        for (int i = 0; i < arr.Length; i++)
        {
            count[arr[i]]++;
        }

        // 更改count[i],现在它包含实际的位置信息
        // 注意,这里是从后往前累加,以确保稳定性
        for (int i = 1; i <= max; i++)
        {
            count[i] += count[i - 1];
        }

        // 构建输出数组arr_copy,并填充排序后的数据
        // 从后向前遍历输入数组,根据计数数组的值,将元素放到正确的位置
        int[] arr_copy = new int[arr.Length];
        for (int i = arr.Length - 1; i >= 0; i--)
        {
            // 将元素放到arr_copy中正确的位置
            // 然后递减count[arr[i]]的值,以确保相同元素的稳定性
            arr_copy[count[arr[i]] - 1] = arr[i];
            count[arr[i]]--;
        }

        // 将排序后的数据复制回原数组
        for (int i = 0; i < arr.Length; i++)
        {
            arr[i] = arr_copy[i];
        }
    }
}

在这个实现中,CountingSort 方法首先找到输入数组 arr 中的最大值,以确定计数数组 count 的大小。然后,它遍历输入数组,计算每个元素的出现次数,并将这些次数存储在计数数组中。

接下来,为了确定每个元素在输出数组中的位置,CountingSort 方法遍历计数数组,并将每个元素的值更新为其前面所有元素值的和(包括它自己)。这样,count[i] 就表示了元素 i 应该放在输出数组中的位置(索引从0开始)。

最后,CountingSort 方法通过遍历输入数组(从后往前遍历以保持稳定性),并使用计数数组来确定每个元素在输出数组中的位置,从而构建了一个排序后的数组 arr_copy。之后,它将排序后的数据复制回原数组 arr

注意,计数排序的时间复杂度为 O(n+k),其中 n 是输入数组的长度,k 是输入数据的范围。这使得计数排序在数据范围不是特别大时非常高效。然而,如果 k 很大,那么计数数组可能会占用大量内存。

  • 6
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

AitTech

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值