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

本文涉及的产品
云解析 DNS,旗舰版 1个月
全局流量管理 GTM,标准版 1个月
公共DNS(含HTTPDNS解析),每月1000万次HTTP解析
简介: 【愚公系列】2021年11月 C#版 数据结构与算法解析(桶排序)

1、桶排序(Bucket Sort)

桶排序是计数排序的升级版。它利用了函数的映射关系,高效与否的关键就在于这个映射函数的确定。桶排序 (Bucket sort)的工作的原理:假设输入数据服从均匀分布,将数据分到有限数量的桶里,每个桶再分别排序(有可能再使用别的排序算法或是以递归方式继续使用桶排序进行排)。


1.1 算法描述

设置一个定量的数组当作空桶;

遍历输入数据,并且把数据一个一个放到对应的桶里去;

对每个不是空的桶进行排序;

从不是空的桶里把排好序的数据拼接起来。

1.2 图片演示

image.png


1.3 代码实现

/// <summary>

/// 桶排序

/// </summary>

public class Program {

   public static void Main(string[] args) {

       double[] array = { 0.43, 0.69, 0.11, 0.72, 0.28, 0.21, 0.56, 0.80, 0.48, 0.94, 0.32, 0.08 };

       BucketSort(array, 10);

       ShowSord(array);

       Console.ReadKey();

   }

   private static void ShowSord(double[] array) {

       foreach (var num in array) {

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

       }

       Console.WriteLine();

   }

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

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

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

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

       foreach (var num in array) {

           int bit = (int)(10 * num);

           bucket[bit, (int)++bucket[bit, 0]] = num;

       }

       //为桶里的每一行使用插入排序

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

           //为桶里的行创建新的数组后使用插入排序

           double[] insertion = new double[(int)bucket[j, 0]];

           for (int k = 0; k < insertion.Length; k++) {

               insertion[k] = bucket[j, k + 1];

           }

           //插入排序

           StraightInsertionSort(insertion);

           //把排好序的结果回写到桶里

           for (int k = 0; k < insertion.Length; k++) {

               bucket[j, k + 1] = insertion[k];

           }

       }

       //将所有桶里的数据回写到原数组中

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

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

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

           }

       }

   }

   public static void StraightInsertionSort(double[] array) {

       //插入排序

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

           double sentinel = array[i];

           int j = i - 1;

           while (j >= 0 && sentinel < array[j]) {

               array[j + 1] = array[j];

               j--;

           }

           array[j + 1] = sentinel;

       }

   }

}

1.4 算法分析

桶排序最好情况下使用线性时间O(n),桶排序的时间复杂度,取决与对各个桶之间数据进行排序的时间复杂度,因为其它部分的时间复杂度都为O(n)。很显然,桶划分的越小,各个桶之间的数据越少,排序所用的时间也会越少。但相应的空间消耗就会增大。


相关文章
|
1月前
|
算法 前端开发 数据处理
小白学python-深入解析一位字符判定算法
小白学python-深入解析一位字符判定算法
48 0
|
1月前
|
存储 算法 Java
解析HashSet的工作原理,揭示Set如何利用哈希算法和equals()方法确保元素唯一性,并通过示例代码展示了其“无重复”特性的具体应用
在Java中,Set接口以其独特的“无重复”特性脱颖而出。本文通过解析HashSet的工作原理,揭示Set如何利用哈希算法和equals()方法确保元素唯一性,并通过示例代码展示了其“无重复”特性的具体应用。
41 3
|
1月前
|
搜索推荐 算法
插入排序算法的平均时间复杂度解析
【10月更文挑战第12天】 插入排序是一种简单直观的排序算法,通过不断将未排序元素插入到已排序部分的合适位置来完成排序。其平均时间复杂度为$O(n^2)$,适用于小规模或部分有序的数据。尽管效率不高,但在特定场景下仍具优势。
|
15天前
|
编译器 C# 开发者
C# 9.0 新特性解析
C# 9.0 是微软在2020年11月随.NET 5.0发布的重大更新,带来了一系列新特性和改进,如记录类型、初始化器增强、顶级语句、模式匹配增强、目标类型的新表达式、属性模式和空值处理操作符等,旨在提升开发效率和代码可读性。本文将详细介绍这些新特性,并提供代码示例和常见问题解答。
33 7
C# 9.0 新特性解析
|
14天前
|
C# 开发者
C# 10.0 新特性解析
C# 10.0 在性能、可读性和开发效率方面进行了多项增强。本文介绍了文件范围的命名空间、记录结构体、只读结构体、局部函数的递归优化、改进的模式匹配和 lambda 表达式等新特性,并通过代码示例帮助理解这些特性。
28 2
|
18天前
|
算法 Linux 定位技术
Linux内核中的进程调度算法解析####
【10月更文挑战第29天】 本文深入剖析了Linux操作系统的心脏——内核中至关重要的组成部分之一,即进程调度机制。不同于传统的摘要概述,我们将通过一段引人入胜的故事线来揭开进程调度算法的神秘面纱,展现其背后的精妙设计与复杂逻辑,让读者仿佛跟随一位虚拟的“进程侦探”,一步步探索Linux如何高效、公平地管理众多进程,确保系统资源的最优分配与利用。 ####
52 4
|
19天前
|
缓存 负载均衡 算法
Linux内核中的进程调度算法解析####
本文深入探讨了Linux操作系统核心组件之一——进程调度器,着重分析了其采用的CFS(完全公平调度器)算法。不同于传统摘要对研究背景、方法、结果和结论的概述,本文摘要将直接揭示CFS算法的核心优势及其在现代多核处理器环境下如何实现高效、公平的资源分配,同时简要提及该算法如何优化系统响应时间和吞吐量,为读者快速构建对Linux进程调度机制的认知框架。 ####
|
9天前
|
算法 C#
C#常见的四种经典查找算法
C#常见的四种经典查找算法
|
9天前
|
算法 C# 索引
C#线性查找算法
C#线性查找算法!
|
1月前
|
存储 算法 C#
C#哈希查找算法
C#哈希查找算法

推荐镜像

更多