排序--希爾排序


圖片轉載於https://www.cnblogs.com/chengxiao/p/6104371.html

1、什么是希爾排序?

希爾排序也是一種插入排序,他是第一個打破時間復雜度O(n^2)的排序方法,它與插入排序的不同之處在於,它會優先比較距離較遠的元素。希爾排序又叫縮小增量排序

2、希爾排序的思想:

希爾排序是把元素按下標的一定增量進行分組,對每組使用直接插入排序算法排序;

隨着增量逐漸減少,當增量減至 1 時整個文件恰被分成一組,算法便終止

3、代碼逐步實現:

排序的元素:
int[] arr={8,9,1,7,2,3,5,4,6,0};

3.1 交換法實現

//第一步 
for (int i=5;i<arr.length;i++){ //i的初始值為初始增量 10/2=5,分為5組,每組兩個元素
            for (int j=i-5;j>=0;j-=5){  //j是距離i為5元素,那么,0和5一組,6和2一組,以此類推,每組比完之后,回退到上一組重新比較,具體用法看第二輪
                if (arr[j+5]<arr[j]){  //比較大小,交換
                    temp=arr[j];
                    arr[j]=arr[j+5];
                    arr[j+5]=temp;
                }
            }
        }
        System.out.println(Arrays.toString(arr));
//第二次
        for (int i=2;i<arr.length;i++){ //這里的2是上次的5/2=2,所以分為兩組,一組5個
            for (int j=i-2;j>=0;j-=2){//距離為2的元素,j-=2是每次比完這一輪重新指向上一分組比較,例如[3,1]和[1,0]兩組,比完[1,0]是[0,1],在和前面比較排序,最后為[0,1,3]
                if (arr[j+2]<arr[j]){
                    temp=arr[j];
                    arr[j]=arr[j+2];
                    arr[j+2]=temp;
                }
            }
        }
        System.out.println(Arrays.toString(arr));
 //第三次
        for (int i=1;i<arr.length;i++){ //i是2/2=1,一共是一組
            for (int j=i-1;j>=0;j-=1){
                if (arr[j+1]<arr[j]){
                    temp=arr[j];
                    arr[j]=arr[j+1];
                    arr[j+1]=temp;
                }
            }
        }
        System.out.println(Arrays.toString(arr));

最后把上面的代碼整合起來:

 //匯總(交換法,花費時間長)
        for (int a=arr.length/2;a>0;a/=2){  //a是增量
            for (int i=a;i<arr.length;i++){
                for (int j=i-a;j>=0;j-=a){
                    if (arr[j+a]<arr[j]){
                        temp=arr[j];
                        arr[j]=arr[j+a];
                        arr[j+a]=temp;
                    }
                }
            }
            System.out.println(Arrays.toString(arr));

上面才用交換的方式實現的排序花費時間大,不推薦使用,按照交換的思路繼續,替換成插入法

3.2 插入法實現:

 1  //匯總(基於插入,花費時間短)
 2         for (int gap=arr.length/2;gap>0;gap/=2){
 3             for (int i=gap;i<arr.length;i++){
 4                     int j=i-gap;
 5                     int temp=arr[i];
 6                     while (j>=0 && temp<arr[j]){
 7                         arr[j+gap]=arr[j];
 8                         j-=gap;
 9                 }
10                     arr[j+gap]=temp;
11             }
12             System.out.println(Arrays.toString(arr));
13 
14         }

從3-10行都是插入法來實現的,可以看出,希爾排序就是對排序的元素進行分組,大大提升了時間

4、時間復雜度

O(n^(1.3—2))

 5、希爾的優勢

希爾排序其實就是在插入排序的基礎上,增加了一個增量,每次為元素划分不同的組
希爾排序在無序的時候,分組多,每個組元素少
隨着增量的變化,分組變少,每個組內元素增加,但組內元素也逐漸變得有序
所以排序起來快(如果原始數據的大部分元素有序,那么插入排序會很快)


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM