数据结构与算法系列——排序(13)_鸽巢排序

1. 工做原理(定义)

  鸽巢排序(Pigeonhole sort),也被称做基数分类,是一种时间复杂度为O(n)(大O符号)且在不可避免遍历每个元素而且排序的状况下效率最好的一种排序算法。

2. 算法步骤

1.  给定一个待排序数组,建立一个备用数组(鸽巢),并初始化元素为0,备用数组的索引便是待排序数组的值。
2. 遍历待排序数组,备用数组(鸽巢)存放索引值的个数。
3. 遍历备用数组(鸽巢),将排序值放回原数组获得排序后的数组的值。

3. 性能分析

1. 时间复杂度

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

  N为待排序数组中最大的元素值。算法

  n为关键字个数数组

2. 空间复杂度

   最坏空间复杂度:O(N*n)性能

3. 算法稳定性 

  稳定的算法。spa

6. 应用

  但它 只有在差值(或者可被映射在差值)很小的范围内的数值排序的状况下实用
  当涉及到多个不相等的元素,且将这些元素放在同一个"鸽巢"的时候,算法的效率会有所下降。为了简便和保持鸽巢排序在适应不一样的状况,好比两个在同一个存储桶中结束的元素必然相等
  咱们通常不多使用鸽巢排序,由于它不多能够在灵活性,简便性,尤是速度上超过其余排序算法。事实上, 桶排序较鸽巢排序更加的实用。

4. 鸽巢排序 & 计数排序 & 桶排序

鸽巢排序的备用数组(鸽巢)存放索引值得个数。
计数排序的备用数组存放的是(对元素值的计数和计数值的累加)来肯定肯定该序列中值小于x的元素的个数,从而将x直接存放到最终的输出序列的正确位置上。
桶排序是鸽巢排序的一种概括结果,桶排序较鸽巢排序更加的实用。是计数排序的升级版本。
 

5. 具体代码

 
public class PigeonholeSort {
    
    /**
     * 鸽巢排序
     * @param array
     * @return
     */
    public static int[] pigeonholeSort(int[] array) {
        int length = array.length;
        int maxNum = getMaxNum(array);
        int pigeonholeSize = maxNum +1;
        int [] auxiliary = new int[pigeonholeSize];
        int j = 0;
        for(int i = 0; i < length; ++i){
            auxiliary[array[i]]++;
        }
        for(int i = 0; i < pigeonholeSize; ++i){
            for(int k = 0; k < auxiliary[i]; ++k){
                array[j++] = i;
            }
                
        }
        return array;
         
    }
    // 获得最大值
    public static int getMaxNum(int[] array){
        int max = array[0];
        for (int i = 0; i < array.length; i++) {
            if(max < array[i]){
                max = array[i];
            }
        }
        return max;
    }
    
    public static void main(String[] args) {
        int[] A=new int[]{73,22, 93, 43, 55, 14, 28, 65, 39, 81};
        A = pigeonholeSort(A);
        for(int num:A) {
            System.out.println(num);
        }
    }
}

6. 参考网址

相关文章
相关标签/搜索