1. 程式人生 > >插入排序—希爾排序(Shell Sort)

插入排序—希爾排序(Shell Sort)

希爾排序是1959 年由D.L.Shell 提出來的,相對直接排序有較大的改進。希爾排序又叫縮小增量排序

基本思想:

先將整個待排序的記錄序列分割成為若干子序列分別進行直接插入排序,待整個序列中的記錄“基本有序”時,再對全體記錄進行依次直接插入排序。

操作方法:

  1. 選擇一個增量序列t1,t2,…,tk,其中ti>tj,tk=1;
  2. 按增量序列個數k,對序列進行k 趟排序;
  3. 每趟排序,根據對應的增量ti,將待排序列分割成若干長度為m 的子序列,分別對各子表進行直接插入排序。僅增量因子為1 時,整個序列作為一個表來處理,表長度即為整個序列的長度。

希爾排序的示例:



演算法實現:

我們簡單處理增量序列:增量序列d = {n/2 ,n/4, n/8 .....1} n為要排序數的個數

即:先將要排序的一組記錄按某個增量dn/2,n為要排序數的個數)分成若干組子序列,每組中記錄的下標相差d.對每組中全部元素進行直接插入排序,然後再用一個較小的增量(d/2)對它進行分組,在每組中再進行直接插入排序。繼續不斷縮小增量直至為1,最後使用直接插入排序完成排序。


# include <stdio.h>

void ShellInsertSort(int a[],int n,int dk){//這個思想就是直接插入排序的思想 
	
	
	for(int i=dk;i<n;i++){//設定哨兵 
		
		int t = a[i]; //記錄當前插入的元素 
		int j = i-dk; //記錄當前最大的元素 
		if(a[i]<a[i-dk]){ //判斷元素是否要排序 
			
			while(t<a[j]&&j>=0){ //需要排序 
				a[j+dk] = a[j];
				j=j-dk;
			}
			a[j+dk] =  t; 
			
		}
		
	}
	
	
}

void shellSort(int a[],int n){ //找出增量,進行分段排序 
	
	int dk=n/2;
	while(dk>=1){
		ShellInsertSort(a,n,dk);
		dk=dk/2;
	}
	
}
int main(){
	
	int a[10]={3,1,5,7,2,4,9,6};  
      
    shellSort(a,8);  
      
    for(int i=0;i<8;i++){  
        printf("%d ",a[i]);  
    }  
    printf("\n");  
	
	return 0;
}