基礎算法-希爾排序的理解與實現-Android版

希爾排序:直接插入排序的進化版,又稱爲“縮小增量排序”; 根據key值,將待排序數列分成若干個子序列,針對每一個子序列進行直接插入排序;然後逐步縮小key值,直到key=1,此時即爲直接插入排序;

例如:       

                         a[] = {5, 3, 9, 6, 2, 1, 4, 0, 8, 7};

假如key=5, 可知{5, 1}===>插入排序後{1 , 5}

                   可知{3, 4}===>插入排序後{3 ,4}

                   可知{9, 0}===>插入排序後{0 , 9}

                   可知{6, 8}===>插入排序後{6 , 8}

                    可知{2,7}===>插入排序後{2 , 7}

最後得到的序列爲    {1, 3, 0, 6, 2, 5, 4, 9, 8, 7}

然後逐步縮減key值,直到key=1, 完成排序。

代碼實現 1: key= a.length/ 2,  即: key = a.length >> 1

                int a[] = {5, 3, 9, 6, 2, 1, 4, 0, 8, 7};
                for (int i = 0; i < a.length; i++) {
                    Log.i("chy==數列初始===", "====" + a[i]);
                }
                /**
                 * 希爾排序外層循環控制循環次數,就是間隔key減少至1的次數
                 */
                for (int gap = a.length >> 1; gap > 0; gap = gap >> 1) {
                    /**
                     * 每一個key, 可以得到諾幹個子序列; 針對每一個子序列做直接插入排序
                     * 當 key=1 時,整個序列爲一個子序列,進行直接插入排序
                     */
                    for (int i = gap; i < a.length; i++) {
                        for (int j = i; j > gap - 1; j = j - gap) {
                            if (a[j - gap] > a[j]) {
                                int temp = a[j];
                                a[j] = a[j-gap];
                                a[j-gap] = temp;
                            } else {
                                break;
                            }
                        }
                    }
                }

                for (int i = 0; i < a.length; i++) {
                    Log.i("chy==輸出結果===", "====" + a[i]);
                }

代碼實現 2: Knuth序列法======>   key= key*3 / 1

                int a[] = {5, 3, 9, 6, 2, 1, 4, 0, 8, 7};
                for (int i = 0; i < a.length; i++) {
                    Log.i("chy==初始結果===", "====" + a[i]);
                }
                /**
                 * 得到 kunth 相對於整個數組的最大值
                 */
                int knuth = 1;
                while (knuth <= a.length/3){
                    knuth = knuth * 3 + 1;
                }
                /**
                 * 希爾排序外層循環控制循環次數,就是間隔key減少至1的次數
                 */
                for (int gap = knuth; gap > 0; gap = (gap-1) /3 ) {
                    /**
                     * 每一個key, 可以得到諾幹個子序列; 針對每一個子序列做直接插入排序
                     * 當 key=1 時,整個序列爲一個子序列,進行直接插入排序
                     */
                    for (int i = gap; i < a.length; i++) {
                        for (int j = i; j > gap - 1; j = j - gap) {
                            if (a[j - gap] > a[j]) {
                                int temp = a[j];
                                a[j] = a[j-gap];
                                a[j-gap] = temp;
                            } else {
                                break;
                            }
                        }
                    }
                }
                for (int i = 0; i < a.length; i++) {
                    Log.i("chy==結果===", "====" + a[i]);
                }

希爾排序記憶: 將待排序數列分成不同段,每段進行直接插入排序;從小序列開始,最後連成一片;上兩種形式只是key 的取值方法不一致,其他的都是一樣的原理

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章