鸽巢排序

关于鸽巢排序的资料很少,下面是从网上找到的一些。

转自:http://www.cnblogs.com/kkun/archive/2011/11/23/2260273.html

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

 

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

原理类似桶排序,同样需要一个很大的鸽巢[桶排序里管这个叫桶,名字无所谓了]

鸽巢其实就是数组啦,数组的索引位置就表示值,该索引位置的值表示出现次数,如果全部为1次或0次那就是桶排序

例如

var pigeonHole = new int[100];

pigeonHole[0]的值表示0的出现次数...

pigeonHole[1]的值表示1的出现次数...

pigeonHole[2]的值表示2的出现次数...

举例

var pigeonHole = new int[10];//10个位置

var A = new int[] { 6, 6, 2, 2, 2, 4, 1, 1, 1, 5, 5, 5, 5, 9 };//待排序数组

foreach (var item in A)

            {

                pigeonHole[item]++;//如pigeonHole[6]++会执行两次,结果为2

            }

鸽巢索引:0 1 2 3 4 5 6 7 8 9

索引次数:0 3 3 0 1 4 2 0 0 1

//顺序输出

for (int i = 0; i < pigeonHole.Length; i++)//索引i就是值

            {

//pigeonHole[i]处的值是数字i出现的次数

//如6出现了两次,那么pigeonHole[6] = 2

//0没出现,那么pigeonHole[0] = 0,表示待排数组里没有这个值:0

for (int j = 0; j < pigeonHole[i]; j++)//i出现就次就输出几个

                {

Console.WriteLine(i);//1,1,1,2,2,2,4,5,5,5,5,6,6,9

                }

            }

参考http://hi.baidu.com/wangxvfeng101/blog/item/a2c22560e57260c58cb10d8c.html

下面来自百度百科:http://baike.baidu.com/view/2020276.htm

 

鸽巢排序

 

鸽巢排序(Pigeonhole sort)

鸽巢排序, 也被称作基数分类, 是一种时间复杂度为(Θ(n))且在不可避免遍历每一个元素并且排序的情况下效率最好的一种排序算法. 但它只有在差值(或者可被映射在差值)很小的范围内的数值排序的情况下实用.
当涉及到多个不相等的元素, 且将这些元素放在同一个"鸽巢"的时候, 算法的效率会有所降低.为了简便和保持鸽巢排序在适应不同的情况, 比如两个在同一个存储桶中结束的元素必然相等
我们一般很少使用鸽巢排序, 因为它很少可以在灵活性, 简便性, 尤是速度上超过其他排序算法. 事实上, 桶排序较鸽巢排序更加的实用.
鸽巢排序的一个比较有名的变形是tally sort, 它仅仅适用非常有限的题目, 这个算法因在Programming Pearls一书中作为解决一个非常规有限集问题方法的例子而著名.
显然, 快速排序可以当作只有两个(有些情况下是三个)"鸽巢"的鸽巢排序

算法效率

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

算法分析

1. 给定一个待排序数组,创建一个备用数组(鸽巢),并初始化元素为0,备用数组的索引即是待排序数组的值。
2.把待排序数组的值,放到“鸽巢”里(即用作备用数组的索引)。
3.把鸽巢里的值再依次送回待排序数组

编辑本段算法代码

算法伪代码(类似Python代码格式)

def pigeonhole_sort ( array a[n] ) :
array auxiliary[N] = {0}
var i ,k
var j = 0
for i = 0 -> n
auxiliary[ a[i] ] ++
for i = 0 -> N
for k = 0 ->auxiliary[i]
a[j++] = i

C源码

函数功能:实现鸽巢排序
参数: *array 为需要排序的数组,length为数组长度
NUM 可以为全局变量 为待排序数组中最大的元素值
void pigeonhole_sort(int* array, int length)  {
int auxiliary[NUM] = {0};
int i, k,j = 0;
for(i = 0; i < length; ++i)
auxiliary[array[i]]++;
for(i = 0; i < NUM; ++i)
for(k = 0; k < auxiliary[i]; ++k)
array[j++] = i;
}
posted @ 2013-06-06 11:33  永不止步,永无止境  阅读(303)  评论(0)    收藏  举报