C#实现鸽巢排序

        /// <summary>
        /// 鸽巢排序
        ///     创建一个长度大于等于待排序数组array元素中最大值的标记数组mark,
        /// 将数组array中元素值个数映射到mark数组中。
        ///     即array数组中的元素值对应mark数组的索引,
        ///       array数组中该元素出现的个数对应mark数组索引的值。
        /// 然后将mark元素中出现的(不等于0)的索引值及个数依次放入array中。
        /// </summary>
        /// <param name="array">待排序数组</param>
        /// <param name="maxValueInArray">数组array中的最大元素值</param>
        public void PigeonholeSort(int[] array, int maxValueInArray)
        {
            int[] mark = new int[maxValueInArray + 1];
            for (int i = 0; i < array.Length; i++)
            {
                ///标记array数组中元素出现的次数
                mark[array[i]]++;
            }
            int arrayIndex = 0;
            ///重新对array的赋值
            for (int i = 0; i < mark.Length; i++)
            {
                ///从array最小元素值 i 开始,i 出现的次数
                for (int j = 0; j < mark[i]; j++)
                {
                    ///依次对数组array的元素更新为最小值 i 及 个数 j
                    array[arrayIndex++] = i;
                }
            }
        }
        /// <summary>
        /// 获取数组array中的最大元素值
        /// </summary>
        /// <param name="array">数组</param>
        /// <returns>最大元素值</returns>
        public int Max(int[] array)
        {
            int max = -1;
            foreach (int item in array)
                if (item > max)
                    max = item;
            return max;
        }

最坏时间复杂度: O(N+n)
最好时间复杂度: O(N+n)
平均时间复杂度: O(N+n)
最坏空间复杂度: O(N*n)

时间: 2025-01-02 15:25:51

C#实现鸽巢排序的相关文章

经典算法之排序问题(二):桶排序、鸽巢排序

鸽巢排序: 鸽巢排序, 也被称作基数分类, 是一种时间复杂度为(Θ(n))且在不可避免遍历每一个元素并且排序的情况下效率最好的一种排序算法. 但它只有在差值(或者可被映射在差值)很小的范围内的数值排序的情况下实用. 当涉及到多个不相等的元素, 且将这些元素放在同一个"鸽巢"的时候, 算法的效率会有所降低.为了简便和保持鸽巢排序在适应不同的情况, 比如两个在同一个存储桶中结束的元素必然相等 我们一般很少使用鸽巢排序, 因为它很少可以在灵活性, 简便性, 尤是速度上超过其他排序算法. 事实

鸽巢排序算法描述和代码举例

//鸽巢排序//适用条件:所有取值的范围确定,并且在这个范围内个元素的出现频率较高.//算法描述:为取值范围内的各个可能取到的元素建巢用一维数组表示,巢中//    巢中存放该元素出现的个数(通过遍历待排序数统计存入).按照巢的//    顺序和巢中元素个数列出该有序序列.//算法空间复杂度为:S(1)时间复杂度为:O(n). //例:20个非负数,其中每个数的取值范围为1~9. #include<iostream>#include<time.h>using namespace s

经典排序算法 - 鸽巢排序Pigeonhole sort

经典排序算法 - 鸽巢排序Pigeonhole sort 原理类似桶排序,同样需要一个很大的鸽巢[桶排序里管这个叫桶,名字无所谓了] 鸽巢其实就是数组啦,数组的索引位置就表示值,该索引位置的值表示出现次数,如果全部为1次或0次那就是桶排序 例如 var pigeonHole = new int[100]; pigeonHole[0]的值表示0的出现次数... pigeonHole[1]的值表示1的出现次数... pigeonHole[2]的值表示2的出现次数... 参考http://hi.bai

ZOJ 2955 Interesting Dart Game(完全背包+鸽巢原理)

题目链接:http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemId=1954 Recently, Dearboy buys a dart for his dormitory, but neither Dearboy nor his roommate knows how to play it. So they decide to make a new rule in the dormitory, which goes as follows

找一个数组中差值绝对值的最小值(鸽巢原理)

给定一个数组a[n],要你求出数组中最小的|a[i]-a[j]|如果只有一个元素就返回0. 貌似是微软的面试题,估计大多数人首先想到的就是排序之后再比较吧,呵呵,是个人都会做.那面试官考你这个问题有毛线意义,这题我们可以用抽屉原理(也叫鸽巢原理)将n个元素放到n+1个桶中(只需要O(n)时间).按如下过程求解: 1首先找出数组中最大的和最小的元素,如果相等,直接返回0 2确定每个桶的大小bucket_size=(maxe-mine)/(n-1) 3将每个元素放到对应的桶id bucket_id=

数组问题(鸽巢原理、数字交换、链表寻环)

287. 寻找重复数 不能更改原数组(假设数组是只读的). 只能使用额外的 O(1) 的空间. 时间复杂度小于 O(n2) . 数组中只有一个重复的数字,但它可能不止重复出现一次. 因为不能能改原来的数组,并且只能使用额外O1的空间,所以我们不能使用map记录,也不能维护一个新的数组 因为时间复杂度要在n2以内,所以暴力查找也是不可取的 因为数据范围在1~n-1,所以可以保证不会数组越界,因此使用链表中快慢指针寻找环算法 https://www.cnblogs.com/fankongkong/p

鸽巢原理简单应用

http://poj.org/problem?id=2356 从n个数里面取出一些数,这些数的和是n的倍数.并输出这些数. 先预处理出前n个数的和用sum[i]表示前i个数的和.若某个sum[i]是n的倍数,直接输出前i个数即可. 否则说明n个数中对n取余的结果有n-1种,即余数为(1~n-1),根据鸽巢原理知必定至少存在两个sum[i]与sum[j]对n取余的结果相等.那么i+1 ~ j之间的数之和一定是n的倍数. #include <stdio.h> #include <iostre

poj 2356 Find a multiple 鸽巢原理的简单应用

题目要求任选几个自然数,使得他们的和是n的倍数. 由鸽巢原理如果我们只选连续的数,一定能得到解. 首先预处理前缀和模n下的sum,如果发现sum[i]==sum[j] 那么(sum[j]-sum[i])%n一定为0,直接输出i+1~j就够了. 为什么一定会有解,因为sum从1~n有n个数,而模n下的数只有0~n-1,把n个数放入0~n-1个数里,怎么也会有重复,所以这种构造方法一定没问题. 其实可以O(n)实现,嫌麻烦,就二重循环无脑了. #include <iostream> #includ

鸽巢原理-poj3370

? 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 #include <stdio.h> int main(int argc, char *argv[]) {         int c = -1, n = -1;         while (true) {         scanf("%d%d",