普通希爾排序算法代碼實現以及思路


先貼上代碼

 1 #include<stdio.h>
 2 #define N 12
 3 //length統計數組的長度 返回最后元素的下標 
 4 int length(int a [N]){
 5     for(int i = 0;i<=N;i++){
 6         if(a[i]==0) return i-1;
 7         
 8     }    
 9 } 
10 //打印輸出數組元素
11 void show(int a[N]){
12     for(int i= 0;i<N;i++){
13         if(a[i]!=0) printf("%4d",a[i]);
14         
15     }    
16 }  
17  //希爾排序  (插入排序升級版) 
18 void shellsort(int a [N]){
19     int gap = length(a)/2 ; 
20     do{
21     int temp=0;
22     for(int i = gap;i<=length(a);i++){
23         for(int j = i;j>=gap;j-=gap){
24             if(a[j-gap]>a[j]){ 
25             temp = a[j-gap] ; 
26               a[j-gap]=a[j]  ;    
27               a[j]=temp;}                   
28         }    
29     } printf("%d\n",gap);    //打印輸出每次循環時gap的數值  輸出值依次為為4 2 1  
30     gap/=2;    
31 }while(gap!=0); //這里可以使用for循環也可以使用do while循環 
32 }
33 int main(void){
34     int a [N] ={2,3,467,1,22,3,5,34,4,7} ; //手動生成數組a 
35     printf("%d\n",length(a));
36     shellsort(a);
37     show(a);  //輸出 1   2   3   3   4   5   7  22  34 467  結果正確 
38     
39     return 0 ;
40 } 

簡單希爾排序算法需要注意的三個關鍵點在於gap值的選擇,以及數組下標i,j和gap的位置關系,要保證程序在gap==1時算法退化成插入排序

以一個簡單的數組 7 6 3 2 4  1為例循環開始時,gap簡寫為g,以括號表示g,i,j所在數字的位置,初始gap=3,數組下標初始值為0,用[]表示需要交換數值的兩個元素,需要注意的是gap處在最外層循環,當i的循環結束時,gap的值才會改變

[7](j-g) 6 3 [2](g,i,j) 4 1 -->2 [6](j-gap) 3 7(g)  [4](i,j) 1 -->2  4 [3](i,j) 7(g) 6 [1](i,j)   //從這里第一次i循環結束,gap/2 =1 退化為簡單的插入排序  -->[2](j-g) [4](g,i,j) 1 7 6 3 -->2 [4](g) [1](i) 7 6 3 --> [2](i-g) [1](g,i,j) 4 7 6 3 --> 1 2 4 7 6 3  依此類推-------->>> 1 2 4 6 7 3 ---->> 1 2 3  6 7 4 --> 1 2  3 4 6 7 (這三次迭代執行的都是j循環 i一直指在數組的最后位置)

--------------------------------------------------------------------------------------------------

對於希爾排序的時間復雜度:

希爾算法的時間復雜度與gap的值選取有關 

在之前的插入排序算法中已經描述過:對於兩個需要交換元素,它們相距越遠,需要交換的次數就越多,於是衍生出了希爾算法,希望解決這個問題。

但是在希爾算法中有兩個不確定因素,①原始數組的元素個數和每個元素的大小是不確定的 ②gap值的選取是不確定的

理論上每個確定數組都應該有一個最優的gap值選取使得希爾排序的時間復雜度為最小的O(NlogN),對於確定的數組我們也很容易選擇每一次循環的gap使得分組排序無效,希爾排序退化成插入排序

這時的時間復雜度為O(N^2)

所以希爾排序的時間復雜度在O(NlogN) 和O(N^2)之間

 


免責聲明!

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



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