希爾排序是把記錄按下標的必定增量分組,對每組使用直接插入排序算法排序;隨着增量逐漸減小,每組包含的關鍵詞愈來愈多,當增量減至1時,整個文件恰被分紅一組,算法便終止。java
分治法的方式,將整個數組拆分紅若干個小的數組,進行一個簡單的直接插入排序。算法
希爾排序就是在直接插入排序的基礎上進行改進的。所以,若是想要理解希爾排序,就先須要瞭解直接插入排序,並且當把二者放在一塊兒的時候,更加容易進行記憶。數組
-----------------------------------------------------------------------------------------------------dom
import java.util.Random; /** * 直接插入排序,說白了,就類比打撲克,拿一張 插一張,插入到合適的位置 * 當拿下一張的時候,保證你在手中的這部分都已經排好順序了。 * @author chf * */ public class Insertion{ public static void main(String[] args) { int[] arr= new int[10]; for(int i=0;i<arr.length;i++){ arr[i]=new Random().nextInt(100); } System.out.println("排序前"); for (int i : arr) { System.out.print(i+" "); } System.out.println(); InsertionSort(arr); System.out.println("排序後"); for (int i : arr) { System.out.print(i+" "); } } public static void InsertionSort(int[] arr){ //起始位置是 第 1 號位置,由於 0 沒有比較的對象,這樣子 默認 0號位置就是已經排好序的。 for(int i=1;i<arr.length;i++){ //每次循環的開始 前面的 那部分數組 已經排好序了,後面的只須要跟前面的已經排好序的進行比較 for(int j=i;j-1>=0;j-=1){ //ps 上面的 for 循環裏面的條件之因此不寫 j-- 是爲了跟 希爾排序作對比 //若是 當前位置的 元素 比當前位置的前一個元素大或者相等,就break,不用比較了 if(arr[j]>=arr[j-1]){ break; } //若是不 break;就符合條件,進行交換 //即當前位置的元素小於 當前位置的前一個元素 //省去中間變量,其實還能夠用 位運算符 arr[j]=arr[j]+arr[j-1];//arr[j]=arr[j]^arr[j-1]; arr[j-1]=arr[j]-arr[j-1];//arr[j-1]=arr[j]^arr[j-1]; arr[j]=arr[j]-arr[j-1];//arr[j]=arr[j]^arr[j-1]; //不過要注意的就是若是 兩個位置的數組 是相等的 ^ 運算會成 0 } } } }
import java.util.Random; /** * 希爾排序 就是 增強版的 直接插入排序 * @author chf * */ public class Shell { public static void main(String[] args) { int[] arr= new int[10]; for(int i=0;i<arr.length;i++){ arr[i]=new Random().nextInt(100); } System.out.println("排序前"); for (int i : arr) { System.out.print(i+" "); } System.out.println(); ShellSort(arr); System.out.println("排序後"); for (int i : arr) { System.out.print(i+" "); } } public static void ShellSort(int[] arr){ int h=1; //首先計算步長,步長也能夠直接是數組 長度的一半,而後每次 除以2 就行 while(h<arr.length/3){ h=h*3+1; } //當步長大於0,也就是等於1的時候,結束後跳出循環 while(h>0){ //直接插入排序是從1 開始,由於 默認 第一個已經排好順序 //這裏面加入了步長,所以默認從 步長的位置開始 //將 0 - h 直接的 數組元素先屏蔽掉,將 0 跟 h 這兩個單獨的元素 組成一個數組 for(int i=h;i<arr.length;i++){ //在直接插入排序中, h 就是1 //若是將全部的h 變成1 就跟 直接插入排序是如出一轍的了 //所以當 步長爲1的時候,其實就是直接插入排序了 for(int j=i;j-h>=0;j-=h){ //排在後面的大,就進行插入排序 if(arr[j]>=arr[j-h]){ break; } arr[j]=arr[j]+arr[j-h];//arr[j]=arr[j]^arr[j-h]; arr[j-h]=arr[j]-arr[j-h];//arr[j-h]=arr[j]^arr[j-h]; arr[j]=arr[j]-arr[j-h];//arr[j]=arr[j]^arr[j-h]; } } //每次步長縮短 h=(h-1)/3; } } }
-------------------------------------------------------------------------------spa
這兩個代碼放一塊,希爾排序就好記了不少。code
---------------------------------------------------------------------------------對象
不保證代碼徹底正確,也不保證代碼是最優。排序
僅僅是根據本身的理解,寫出來直觀的代碼,方便理解。io
錯誤請指出,感激涕零!class