希爾排序算法思想:
爲了易於理解,把要排序的數當成一系列整數,讓這些整數組成一個長度爲n(n爲這些要排序的整數的個數)的數組爲例來說明。取一個小於要排序的數字的個數n的整數a,把要排序的數字分成a個小數組(這些小數組中的元素由原數組中所有距離爲a和a的倍數的位置處的整數組成),然後對這些小數組進行直接插入排序。完成之後,再取一個整數a1(a1<a),然後重複上面的操作,即進行分組和直接插入排序,直到at=1(at<at-1<···a2<a1)即所有的整數放在同一個數組中進行直接插入排序爲止。簡而言之,就是一種分組的直接插入排序方法。
希爾排序的過程如下:
比如對下面的整數進行希爾排序爲例來說明:
2,4,1,3
這些整數的個數爲n=4,用等於2的整數a1(a1=n/2)把這些數分割成兩部分,分割的方法就是:將相隔2個數的距離的整數分配到一個數組。因此可以等到兩個數組{2,1}
和{4,3},對這兩個數組進行直接插入排序後爲{1,2}和{3,4},這樣它們原數列中的順序就變成了:1,3,2,4
然後讓a2=a1/2=1,繼續對當前的數列進行排序,於是就把當前的數列分成了一個新的數組(間隔一個元素的距離組成的數組){1,3,2,4}然後對這個數組進行直接插入排序,於是就變成了1,2,3,4,此時a2=1,排序完畢。
希爾排序核心代碼如下:
public void shellSort(int[] arr){
int temp;//定義一個臨時值
boolean isChange;//判斷數組中元素的排列順序是否有變化,如果有變化,就把當前數組中的元素打印出來
int splitLength;//定義數組中要排序的元素的間隔距離
int point;//找出當前要排序的元素的位置,即該元素在數組中位置的下標值
splitLength=(int)arr.length/2;//規定間隔長度
while(splitLength!=0){//如果間隔長度不爲0
/**下面的for循環的作用是
*/
for(int i=splitLength;i<arr.length;i++){
isChange=false;//設置isChange的初始值爲false
temp=arr[i];//讓
point=i-splitLength;
while(temp<arr[point]&&point>=0&&point<=arr.length){//如果第一個值比後面的值大
arr[point+splitLength]=arr[point];//把這個元素放在後面的位置
point=point-splitLength;
isChange=true;
if(point<0||point>arr.length){
break;
}
}
arr[point+splitLength]=temp;
if(isChange){
System.out.print("排序中:");
for(int j=0;j<arr.length;j++){
System.out.printf("%3s", arr[j]);
}
System.out.println("");
}
}
splitLength=splitLength/2;
}
System.out.println("希爾排序完成!");
}
舉例說明如下:
package AlgorithmTest;
/**
*
* @author Administrator
*/
public class ShellSortTest {
public static void main(String args[]){
int[] a={2,4,1,3};
ShellSortTest sst=new ShellSortTest();
sst.shellSort(a);
}
public void shellSort(int[] arr){
int temp;//定義一個臨時值
boolean isChange;//判斷數組中元素的排列順序是否有變化,如果有變化,就把當前數組中的元素打印出來
int splitLength;//定義數組中要排序的元素的間隔距離
int point;//找出當前要排序的元素的位置,即該元素在數組中位置的下標值
splitLength=(int)arr.length/2;//規定間隔長度
while(splitLength!=0){//如果間隔長度不爲0
/**下面的for循環的作用是
*/
for(int i=splitLength;i<arr.length;i++){
isChange=false;//設置isChange的初始值爲false
temp=arr[i];//讓
point=i-splitLength;
while(temp<arr[point]&&point>=0&&point<=arr.length){//如果第一個值比後面的值大
arr[point+splitLength]=arr[point];//把這個元素放在後面的位置
point=point-splitLength;
isChange=true;
if(point<0||point>arr.length){
break;
}
}
arr[point+splitLength]=temp;
if(isChange){
System.out.print("排序中:");
for(int j=0;j<arr.length;j++){
System.out.printf("%3s", arr[j]);
}
System.out.println("");
}
}
splitLength=splitLength/2;
}
System.out.println("希爾排序完成!");
showArray(arr);
System.out.println();
}
public void showArray(int[] arr){
for(int i=0;i<arr.length;i++){
System.out.print(arr[i]+" ");
}
}
}