# 算法实例 #

排序算法Sort

信箱排序PigeonHoleSort

https://en.wikipedia.org/wiki/Pigeonhole_sort

算法說明

1.信箱算法使用一個完整的序列來存放排序後的數據
2.我們常用的序列是不連續的,{2,3,5,2}中間缺少了元素{4},而信箱算法的存放序列是連續的我們如果以最小的元素{2}來定位,每個位置只是表示其有多少個相同的元素那麼{2,3,5,2}可以表示成{2,1,0,1}[即連續空間中有兩個2,壹個3,零個4,壹個5]
3.該算法的問題在於,先要知道最大數和最小數.
4.如果不知道最大數和最小數,使用該算法將會有額外的開銷用於尋找最大和最小數.
5.由於是需要連續空間的存放,所以算法只支持int類型,不然創造的連續空間長度不可控.

算法步驟

1.找到序列中的最大和最小數
2.確定完整空間大小size=max-min+1
3.計算每個信箱格的元素個數
4.去掉完整序列的零個數元素,生成排序后的非完整序列.

代碼示例
https://github.com/aalhour/C-Sharp-Algorithms/blob/master/Algorithms/Sorting/PigeonHoleSorter.cs

/// <summary>
/// Only support IList<int> Sort
/// Also called CountSort (not CountingSort)
/// </summary>
public static class PigeonHoleSorter
{
    public static void PigeonHoleSort(this IList<int> collection)
    {
        collection.PigeonHoleSortAscending();
    }

    public static void PigeonHoleSortAscending(this IList<int> collection)
    {
        int min = collection.Min();
        int max = collection.Max();
        int size = max - min + 1;
        int[] holes = new int[size];
        foreach (int x in collection)
        {
            holes[x - min]++;
        }

        int i = 0;
        for (int count = 0; count < size; count++)
        {
            while (holes[count]-- > 0)
            {
                collection[i] = count + min;
                i++;
            }
        }
    }

    public static void PigeonHoleSortDescending(this IList<int> collection)
    {
        int min = collection.Min();
        int max = collection.Max();
        int size = max - min + 1;
        int[] holes = new int[size];
        foreach (int x in collection)
        {
            holes[x - min]++;
        }

        int i = 0;
        for (int count = size-1; count >= 0; count--)
        {
            while (holes[count]-- >0)
            {
                collection[i] = count + min;
                i++;
            }
        }
    }
}

測試用例

    [TestMethod]
    public void TestMethod2()
    {
        List<int> list = new List<int>() { 23, 42, 4, 16, 8, 23, 15, 3, 9, 55, 0, 23, 34, 12, 2, 46, 25, 25 };
        list.PigeonHoleSort();
    }

算法構造的完整序列

算法實例-C#-信箱排序-PigeonHoleSort的更多相关文章

  1. 算法實例-C#-歸併排序-MergeSort

    # 算法实例 # 排序算法Sort 歸併排序MergeSort 算法說明 歸併的思路是任意兩個元素可以比較大小,那麼任意兩個有序的元素集合也可以通過比較大小的方式歸併成一個有序的元素集合 任何的無序元 ...

  2. 算法-java代码实现计数排序

    计数排序   第10节 计数排序练习题 对于一个int数组,请编写一个计数排序算法,对数组元素排序. 给定一个int数组A及数组的大小n,请返回排序后的数组. 测试样例: [1,2,3,5,2,3], ...

  3. 算法-java代码实现希尔排序

    希尔排序 第8节 希尔排序练习题 对于一个int数组,请编写一个希尔排序算法,对数组元素排序. 给定一个int数组A及数组的大小n,请返回排序后的数组.保证元素小于等于2000. 测试样例: [1,2 ...

  4. 常见排序算法总结:插入排序,希尔排序,冒泡排序,快速排序,简单选择排序以及java实现

    今天来总结一下常用的内部排序算法.内部排序算法们需要掌握的知识点大概有:算法的原理,算法的编码实现,算法的时空复杂度的计算和记忆,何时出现最差时间复杂度,以及是否稳定,何时不稳定. 首先来总结下常用内 ...

  5. 数据结构与算法——认识O(NlogN)的排序(2)

    输入整型数组和排序标识,对其元素按照升序或降序进行排序 (一组测试用例可能会有多组数据) 接口说明 原型: void sortIntegerArray(Integer[] pIntegerArray, ...

  6. SpringMVC常用注解實例詳解3:@ResponseBody

    我的開發環境框架:        springmvc+spring+freemarker開發工具: springsource-tool-suite-2.9.0JDK版本: 1.6.0_29tomcat ...

  7. SpringMVC常用注解實例詳解2:@ModelAttribute

    我的開發環境框架:        springmvc+spring+freemarker開發工具: springsource-tool-suite-2.9.0JDK版本: 1.6.0_29tomcat ...

  8. RTX的api開發實例

    RTX的api開發實例 最近接觸了RTX的接口開發部份,RTX其实有很多玩法,除了可以用自帶的客戶端發消息之外還可以用PHP調用API的方式來做一些事情,下邊整理了一下分享給大家 值得提醒的是这些接口 ...

  9. 簡單SQL存儲過程實例

    簡單SQL存儲過程實例 摘自:http://blog.csdn.net/libra6956/article/details/5589173 实例1:只返回单一记录集的存储过程. 银行存款表(bankM ...

随机推荐

  1. MySQL记录

    1.unixtime和可读时间的转换 unixtime是距"1970-01-01 08:00:00"的时间秒数 unixtime -> readable select fro ...

  2. Java程序员的日常—— POI与JDBC、Mockmvc与单元测试

    周日没怎么休息好,周一一天都迷迷糊糊的,不过还算是干了不少的活. 总结一下,大致有以下几点内容: 1 使用poi以及mysql jdbc实现了一个复杂excel的导入 2 基于工程原有的代码,书写sp ...

  3. [源码解析]HashMap和HashTable的区别(源码分析解读)

    前言: 又是一个大好的周末, 可惜今天起来有点晚, 扒开HashMap和HashTable, 看看他们到底有什么区别吧. 先来一段比较拗口的定义: Hashtable 的实例有两个参数影响其性能:初始 ...

  4. Atitit Server Side Include  ssi服务端包含规范 csi  esi

    Atitit Server Side Include  ssi服务端包含规范 csi  esi 一.CSI (Client Side Includes)  1 1.1. 客户端包含1 1.2. Ang ...

  5. Linux设置SFTP服务用户目录权限

    我们有时会遇到这样的需求,限制一个Linux用户,让他只能在指定的目录下进行添加.修改.删除操作,并且只能使用sftp登录服务器,不能用ssh操作.这些可以通过配置sftp服务实现. 提供sftp服务 ...

  6. Liferay7 BPM门户开发之43: Gradle依赖管理

    进入liferay v7.0,官方推荐使用Gradle进行依赖管理和发布,所以必须知道Gradle的用法,网上资料很多,不赘述 只写依赖管理的分类 一般用外部仓库依赖,也可以用本地文件依赖(依赖本地j ...

  7. 锁&锁与指令原子操作的关系 & cas_Queue

    锁 锁以及信号量对大部分人来说都是非常熟悉的,特别是常用的mutex.锁有很多种,互斥锁,自旋锁,读写锁,顺序锁,等等,这里就只介绍常见到的, 互斥锁 这个是最常用的,win32:CreateMute ...

  8. struts之动态方法调用使用通配符

    一.DMI动态方法调用的其中一种改变form表单中action属性的方式已经讲过了.还有两种,一种是改变struts.xml配置文件中action标签中的method属性,来指定执行不同的方法处理不同 ...

  9. C++标准库vector类型详解

    Vector简介 vector是定义在C++标准模板库,它是一个多功能.能够操作多种数据结构和算法的模板类(关于模板类我们后面会介绍,如何创建自己的模板类).vector是一个容器,能够像容器一样存放 ...

  10. 【WP 8.1开发】手机客户端应用接收推送通知

    上一篇文章中,已经完成了用于发送通知的服务器端,接下来我们就用这个服务端来测试一下. 在开始测试之前,我们要做一个接收通知的WP应用. 1.启动VS Express for Windows,新建项目, ...