數據結構與算法系列——排序(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. 參考網址

相關文章
相關標籤/搜索