1、Shell排序算法的介紹
希爾排序,也稱遞減增量排序算法,是直接插入排序算法的一種高速而穩定的改進版本。
希爾排序是把記錄按下標的一定增量分組,對每組使用直接插入排序算法排序;隨着增量逐漸減少,每組包含的關鍵詞越來越多,當增量減至1時,整個文件恰被分成一組,算法便終止。
先取一個小於n的整數d1作為第一個增量,把文件的全部記錄分組。所有距離為d1的倍數的記錄放在同一個組中。先在各組內進行直接插入排序;然后,取第二個增量d2<d1重復上述的分組和排序,直至所取的增量=1(<…<d2<d1),即所有記錄放在同一組中進行直接插入排序為止。
2、Shell排序算法的特點
- 希爾排序是基於插入排序的以下兩點性質而提出改進方法的:
- 插入排序在對幾乎已經排好序的數據操作時, 效率高, 即可以達到線性排序的效率
- 但插入排序一般來說是低效的, 因為插入排序每次只能將數據移動一位
- 時間復雜度:最壞情況下為O(n^2),平均時間復雜度為O(nlogn);
- 空間復雜度:歸並排序需要一個大小為1的臨時存儲空間用以保存合並序列,所以空間復雜度為O(1)
- 算法穩定性:從上面圖片中可以看出,數字5在排序后交換了位置,所以它是不穩定的算法。
3、Shell排序算法的代碼實現
1 package com.baozi.paixu; 2 3 import java.util.Arrays; 4 5 /** 6 * 希爾排序算法 7 * @author BaoZi 8 * @create 2019-05-15-17:41 9 */ 10 public class ShellSort { 11 public static void main(String[] args) { 12 int[] nums = new int[]{8, 3, 2, 1, 7, 4, 6, 5}; 13 System.out.println("........排序之前的數組........"); 14 System.out.println(Arrays.toString(nums)); 15 System.out.println("........排序之后的數組........"); 16 ShellSort.shellSort(nums); 17 System.out.println(Arrays.toString(nums)); 18 } 19 20 /** 21 * shellSort排序算法的實現 22 * 增量h=(h*3)+1; 這個增量公式是由Knuth給出的 23 * 24 * @param nums 25 */ 26 public static void shellSort(int[] nums) { 27 int len = nums.length; 28 //1、首先根據數組的長度確定增量的最大值 29 int h = 1; 30 //按h * 3 + 1得到增量序列的最大值 31 while (h <= len / 3) { 32 h = h * 3 + 1; 33 } 34 //進行增量查找和排序 35 while (h > 0) { 36 for (int i = h; i < len; i++) { 37 for (int k = i; k < len; k = k + h) { 38 //判斷是否需要重新排序,如果小於k-h處的值,需要重新排序 39 if (nums[k] < nums[k - h]) { 40 int temp = nums[k]; 41 int j = k; 42 for (; j >= i && temp < nums[j - h]; j -= h) { 43 nums[j] = nums[j - h]; 44 } 45 nums[j] = temp; 46 } 47 } 48 } 49 h = (h - 1) / 3; 50 } 51 } 52 }