首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >C#计数排序算法

C#计数排序算法

原创
作者头像
Michel_Rolle
发布2024-10-10 23:16:05
发布2024-10-10 23:16:05
3K00
代码可运行
举报
文章被收录于专栏:c#分享专栏c#分享专栏
运行总次数:0
代码可运行

计数排序(Counting Sort)是一种非比较型整数排序算法,其核心在于将输入的数字映射到数组索引上。与传统排序算法相比,计数排序在处理特定类型的数据时(如整数或小范围的值)具有非常高的效率。该算法的时间复杂度通常为O(n + k),其中n是待排序数组中的元素数量,k是数组中最大和最小元素的差值。

计数排序的基本原理

计数排序的基本思想是:对于给定的一组数据,我们首先统计每个值出现的次数,然后根据这些计数来确定每个元素在排序后数组中的位置。算法的步骤如下:

  1. 找出待排序数组中的最大值和最小值。
  2. 创建一个新的数组,其长度为最大值和最小值之差加一。
  3. 遍历原数组,对于数组中的每个元素,将其对应的计数数组元素加一。
  4. 再次遍历计数数组,将每个元素累加,从而得到每个值在排序后数组中的最终位置。
  5. 根据计数数组构建排序后的数组。

计数排序的算法步骤

  1. 确定最大值和最小值:首先遍历整个数组,找到最大值和最小值。
  2. 创建计数数组:初始化一个长度为最大值和最小值之差的数组,并将其所有元素设置为0。
  3. 填充计数数组:再次遍历原数组,对于数组中的每个元素,将其对应的计数数组元素加一。
  4. 累加计数数组:对计数数组进行累加,从而得到每个值在排序后数组中的最终位置。
  5. 构建排序数组:根据累加后的计数数组构建排序后的数组。

计数排序的C#实现

下面是一个计数排序算法的C#实现示例:

代码语言:javascript
代码运行次数:0
运行
复制
using System;

class Program
{
    static void CountingSort(int[] arr)
    {
        int max = arr[0];
        int min = arr[0];
        
        // 找出最大值和最小值
        for (int i = 1; i < arr.Length; i++)
        {
            if (arr[i] > max)
                max = arr[i];
            if (arr[i] < min)
                min = arr[i];
        }

        int range = max - min + 1;
        int[] count = new int[range];
        int[] output = new int[arr.Length];
        
        // 初始化计数数组
        for (int i = 0; i < arr.Length; i++)
        {
            count[arr[i] - min]++;
        }

        // 累加计数数组
        for (int i = 1; i < count.Length; i++)
        {
            count[i] += count[i - 1];
        }

        // 构建排序数组
        for (int i = arr.Length - 1; i >= 0; i--)
        {
            output[count[arr[i] - min] - 1] = arr[i];
            count[arr[i] - min]--;
        }

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

    static void Main()
    {
        int[] arr = { 4, 2, 2, 8, 3, 3, 1 };
        int n = arr.Length;

        Console.WriteLine("Given array is ");
        foreach (int value in arr)
        {
            Console.Write(value + " ");
        }

        CountingSort(arr);

        Console.WriteLine("\nSorted array is ");
        foreach (int value in arr)
        {
            Console.Write(value + " ");
        }
    }
}

在这个示例中,我们首先定义了一个未排序的整数数组arr。然后,我们使用CountingSort方法对数组进行排序。CountingSort方法首先找出数组中的最大值和最小值,然后创建并初始化计数数组,接着填充计数数组并累加计数,最后根据累加后的计数数组构建排序后的数组。

计数排序的性能分析

计数排序的时间复杂度通常为O(n + k),其中n是待排序数组中的元素数量,k是数组中最大和最小元素的差值。由于计数排序不是基于比较的排序算法,因此它在处理特定类型的数据时(如整数或小范围的值)具有非常高的效率。

计数排序的空间复杂度是O(k),因为我们需要额外的存储空间来存储计数数组。

计数排序的优化

尽管计数排序在特定情况下非常高效,但在某些情况下,其性能可能会受到影响。例如,当k的值非常大时,计数排序的空间复杂度会很高。为了优化计数排序,可以采取以下措施:

  1. 使用更小的基数:如果数据的范围非常大,可以考虑使用基数为2或4的计数排序,这样可以减少计数数组的大小。
  2. 使用线性计数数组:对于小范围的值,可以使用线性计数数组来减少空间复杂度。
  3. 与其他排序算法结合:对于大数据集,可以先使用快速排序或归并排序对数据进行粗略排序,然后再使用计数排序进行精细排序。

下面是一个优化后的计数排序算法的C#实现示例,使用线性计数数组:

代码语言:javascript
代码运行次数:0
运行
复制
using System;

class Program
{
    static void CountingSort(int[] arr, int max)
    {
        int[] count = new int[max + 1];
        int[] output = new int[arr.Length];
        
        // 初始化计数数组
        for (int i = 0; i < arr.Length; i++)
        {
            count[arr[i]]++;
        }

        // 累加计数数组
        for (int i = 1; i < count.Length; i++)
        {
            count[i] += count[i - 1];
        }

        // 构建排序数组
        for (int i = arr.Length - 1; i >= 0; i--)
        {
            output[count[arr[i]] - 1] = arr[i];
            count[arr[i]]--;
        }

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

    static void Main()
    {
        int[] arr = { 4, 2, 2, 8, 3, 3, 1 };
        int max = 8; // 假设我们知道最大值

        Console.WriteLine("Given array is ");
        foreach (int value in arr)
        {
            Console.Write(value + " ");
        }

        CountingSort(arr, max);

        Console.WriteLine("\nSorted array is ");
        foreach (int value in arr)
        {
            Console.Write(value + " ");
        }
    }
}

在这个优化后的示例中,我们使用线性计数数组来减少空间复杂度。

计数排序的应用场景

计数排序适用于以下场景:

  1. 数据范围较小:当数据范围较小时,计数排序的空间复杂度较低,效率较高。
  2. 大量重复数据:当数据集中存在大量重复数据时,计数排序可以快速完成排序。
  3. 非负整数排序:计数排序适用于非负整数的排序,特别是当数据范围较小时。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 计数排序的基本原理
  • 计数排序的算法步骤
  • 计数排序的C#实现
  • 计数排序的性能分析
  • 计数排序的优化
  • 计数排序的应用场景
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档