【愚公系列】2021年11月 C#版 数据结构与算法解析(基数排序)

简介: 【愚公系列】2021年11月 C#版 数据结构与算法解析(基数排序)

1、基数排序(Radix Sort)

基数排序是按照低位先排序,然后收集;再按照高位排序,然后再收集;依次类推,直到最高位。有时候有些属性是有优先级顺序的,先按低优先级排序,再按高优先级排序。最后的次序就是高优先级高的在前,高优先级相同的低优先级高的在前。


1.1 算法描述

取得数组中的最大数,并取得位数;

arr为原始数组,从最低位开始取每个位组成radix数组;

对radix进行计数排序(利用计数排序适用于小范围数的特点);

1.2 动图演示

image.png


1.3 代码实现

/// <summary>

/// 基数排序

/// </summary>

public class Program {

   public static void Main(string[] args) {

       int[] array = { 43, 69, 11, 72, 28, 21, 56, 80, 48, 94, 32, 8 };

       RadixSort(array, 10);

       ShowSord(array);

       Console.ReadKey();

   }

   private static void ShowSord(int[] array) {

       foreach (var num in array) {

           Console.Write($"{num} ");

       }

       Console.WriteLine();

   }

   public static void RadixSort(int[] array, int bucketNum) {

       int maxLength = MaxLength(array);

       //创建bucket时,在二维中增加一组标识位,其中bucket[x, 0]表示这一维所包含的数字的个数

       //通过这样的技巧可以少写很多代码

       int[,] bucket = new int[bucketNum, array.Length + 1];

       for (int i = 0; i < maxLength; i++) {

           foreach (var num in array) {

               int bit = (int)(num / Math.Pow(10, i) % 10);

               bucket[bit, ++bucket[bit, 0]] = num;

           }

           for (int count = 0, j = 0; j < bucketNum; j++) {

               for (int k = 1; k <= bucket[j, 0]; k++) {

                   array[count++] = bucket[j, k];

               }

           }

           //最后要重置这个标识

           for (int j = 0; j < bucketNum; j++) {

               bucket[j, 0] = 0;

           }

       }

   }

   private static int MaxLength(int[] array) {

       if (array.Length == 0) return 0;

       int max = array[0];

       for (int i = 1; i < array.Length; i++) {

           if (array[i] > max) max = array[i];

       }

       int count = 0;

       while (max != 0) {

           max /= 10;

           count++;

       }

       return count;

       //return (int)Math.Log10(max) + 1;

   }

}

1.4 算法分析

基数排序基于分别排序,分别收集,所以是稳定的。但基数排序的性能比桶排序要略差,每一次关键字的桶分配都需要O(n)的时间复杂度,而且分配之后得到新的关键字序列又需要O(n)的时间复杂度。假如待排数据可以分为d个关键字,则基数排序的时间复杂度将是O(d*2n) ,当然d要远远小于n,因此基本上还是线性级别的。


基数排序的空间复杂度为O(n+k),其中k为桶的数量。一般来说n>>k,因此额外空间需要大概n个左右。


相关文章
|
5天前
|
存储 开发框架 .NET
C#中将DataTable转化成ListT的方法解析
C#中将DataTable转化成ListT的方法解析
6 0
|
5天前
|
XML 存储 开发框架
c#教你网站数据轻松解析抓取,HtmlAgilityPack解析的奇妙之处
c#教你网站数据轻松解析抓取,HtmlAgilityPack解析的奇妙之处
8 0
|
14天前
|
存储 机器学习/深度学习 算法
|
16天前
|
机器学习/深度学习 数据采集 人工智能
【热门话题】AI作画算法原理解析
本文解析了AI作画算法的原理,介绍了基于机器学习和深度学习的CNNs及GANs在艺术创作中的应用。从数据预处理到模型训练、优化,再到风格迁移、图像合成等实际应用,阐述了AI如何生成艺术作品。同时,文章指出未来发展中面临的版权、伦理等问题,强调理解这些算法对于探索艺术新境地的重要性。
30 3
|
17天前
|
存储 算法 安全
|
18天前
|
存储 NoSQL Redis
Redis入门到通关之数据结构解析-IntSet
Redis入门到通关之数据结构解析-IntSet
22 1
|
18天前
|
存储 NoSQL Redis
Redis入门到通关之数据结构解析-SkipList
Redis入门到通关之数据结构解析-SkipList
30 0
|
18天前
|
存储 NoSQL Redis
Redis入门到通关之数据结构解析-QuickList
Redis入门到通关之数据结构解析-QuickList
25 0
|
18天前
|
存储 NoSQL 安全
Redis入门到通关之数据结构解析-动态字符串SDS
Redis入门到通关之数据结构解析-动态字符串SDS
18 0
|
2天前
PandasTA 源码解析(二十三)
PandasTA 源码解析(二十三)
8 0

推荐镜像

更多