排序算法-希尔排序
文章目錄
- 1、簡單插入排序存在的問題
- 2、希爾排序算法介紹
- 3、希爾排序的基本思想
- 4、圖示分析希爾排序
- 5、代碼實現(交換式)
- 6、代碼實現(移位式)
- 7、時間復雜度
- 8、穩定性
1、簡單插入排序存在的問題
我們看簡單的插入排序可能存在的問題。
數組 arr = {2,3,4,5,6,1} 這是需要插入的數 1(最小),這樣的過程是:
{2,3,4,5,1,6}
{2,3,4,1,5,6}
{2,3,1,4,5,6}
{2,1,3,4,5,6}
{1,2,3,4,5,6}
結論:當需要插入放入數是較小的數時,后移的次數明顯增多,對效率有影響
2、希爾排序算法介紹
希爾排序也是一種插入排序,它是簡單插入排序經過改進之后的一個更高效的版本,也稱為最小增量排序
3、希爾排序的基本思想
希爾排序就是把記錄按下標的一定增量分組,對每組使用直接插入排序算法排序;隨著增量主鍵減少,每組包含的關鍵詞越來越多,當增量減至 1 時,整個元素恰被分成一組,算法便終止。
4、圖示分析希爾排序
-
將數的個數設為n,取奇數k=n/2,將下標差值為k的書數為一組,構成有序序列。
-
再取k=k/2 ,將下標差值為k的數分為一組,構成有序序列。
-
重復第二步,直到k=1執行簡單插入排序。
增量d 的范圍:1<= d < 待排序數組的長度 (d 需為 int 值)
增量的取值:一般的初次取序列(數組)的一半為增量,以后每次減半,直到增量為1。
第一個增量 = 數組的長度/2,
第二個增量 = 第一個增量/2,
第三個增量 = 第二個增量/2,
以此類推,最后一個增量=1。
如何寫成代碼:
- 首先確定分的組數。
- 然后對組中元素進行插入排序。
- 然后將length/2,重復1,2步,直到length=0為止。
5、代碼實現(交換式)
/*** 交換式 希爾排序* @param arr 待排序的數組*/public static void shellSort(int [] arr){//組數int a = arr.length / 2;int temp = 0; //用于交換的變量do {for (int i = a; i < arr.length; i++) {for (int j = i - a ; j >= 0 ; j -= a) {if (arr[j] > arr[j+a]){temp = arr[j];arr[j] = arr[j+a];arr[j+a] = temp;}}}System.out.println(Arrays.toString(arr));a /= 2;}while (a > 0);}6、代碼實現(移位式)
/*** 移位式 希爾排序* @param arr 待排序的數組*/public static void shellSort2(int [] arr){for (int gap = arr.length / 2; gap > 0; gap/=2) {for (int i = gap; i < arr.length; i++) {int j = i;int temp = arr[j];if (arr[j] < arr[j - gap]){while ((j - gap) >= 0 && temp < arr[j-gap]){arr[j] = arr[j-gap];j -= gap;}arr[j] = temp;}}}}7、時間復雜度
最好情況:序列是正序排列,在這種情況下,需要進行的比較操作需(n-1)次。后移賦值操作為0次。即O(n)
最壞情況:O(nlog2n)。
8、穩定性
由于多次插入排序,我們知道一次插入排序是穩定的,不會改變相同元素的相對順序,但在不同的插入排序過程中,相同的元素可能在各自的插入排序中移動,最后其穩定性就會被打亂,所以希爾排序是不穩定的。
總結
- 上一篇: 深入了解模电数电目录篇
- 下一篇: PHP检查日期格式是否符合