十六 排序演算法(二) 希爾排序演算法

2021-07-03 01:26:41 字數 1863 閱讀 2855

1、希爾排序

演算法步驟:

通俗的說法:

1. 將乙個長度為len的待排序列,依照某個間距gap,分割成len/gap份;

2. 對這每個子串行進行插入排序;

3. 完成後,將gap減小,再執行上述過程;

4. 直到gap為1時,排序完成!

演算法實現:

/*

用於交換兩個元素的值

*/void swap(int *array, int i, int j)

/*

希爾排序演算法

通俗的說法:

將乙個長度為len的待排序列,依照某個間距gap,分割成len/gap份,對這每個子串行進行插入排序;

完成後,將gap減小,再執行上述過程;

直到gap為1時,排序完成!

*/void shellsort(int *array, int len)

#ifdef _statistics_

jsum++;

#endif

}#ifdef _statistics_

isum++;

#endif

}#ifdef _statistics_

zsum++;

#endif

}}while(gap > 1);

#ifdef _statistics_

printf("jsum=%d\tisum=%d\tzsum=%d\t\n",jsum,isum,zsum);

#endif

}

使用上述的實現方法,在排列乙個7元素序列時,每個迴圈的執行次數如下:

可見時間複雜度很高,內層迴圈居然執行了112次!!

2、已有演算法的改進

/*

希爾排序演算法

對上述shellsort實現的改進:

按照上面的描述來說,假如乙個待排序列被分割成了3個子序列,那麼理應迴圈3次,分別對

這3個子序列進行插入排序,然後再使gap減小,再進行下一次分割和排序,但是這樣寫,上方

的三個函式的執行次數會很多,演算法的時間複雜度很高!

改進:因為希爾排序演算法,當gap為1時,實際上就是乙個插入排序演算法,也就是說,無論如何,一旦

gap為1,序列就能被排好,所以再待排序列被分割成幾個子串行後,我們可以只做第乙個子序

列的插入排序工作,這樣能很好的減少演算法的時間複雜度,也就少了一層迴圈!

*/void shell_sort(int *array, int len)

#ifdef _statistics_

jsum++;

#endif

}#ifdef _statistics_

isum++;

#endif

}#ifdef _statistics_

zsum++;

#endif

}while(gap > 1);

#ifdef _statistics_

printf("jsum=%d\tisum=%d\tzsum=%d\t\n",jsum,isum,zsum);

#endif

}

實際測試:

可見時間複雜度減小了很多,內層迴圈由112次減少到了30次!!

編譯步驟:

0.1 解壓縮:tar -zxvf shellsort-1.0.tar.gz

0.2 編譯:gcc -std=c99 -wall -g shellsort.c -o shellsort

0.3 執行:./shellsort

排序演算法(二) 希爾排序

主要思想 先將待排序列分割成若干個子串行,在子串行內分別進行直接插入排序,待整個序列基本有序時,再對全體記錄進行直接插入排序。例如 第一趟 d 5,將所有相距為 5 的記錄分為一組,從而將整個序列分割成了 5 個子序列。第二趟 d 2,將所有相距為 2 的記錄分為一組,從而將整個序列分割成了8 個子...

排序演算法(二)希爾排序

希爾排序 shell sort 是插入排序的一種。也稱縮小增量排序,是直接插入排序演算法的一種更高效的改進版本。public static int shellsort int a 希爾排序 時間複雜度 希爾排序的時間複雜度與增量序列的選取有關,例如希爾增量時間複雜度為o n 而hibbard增量的希...

排序演算法 二 希爾排序

希爾排序是1959 年由d.l.shell 提出來的,相對直接插入排序有較大的改進。希爾排序又叫縮小增量排序 基本思想 先將整個待排序的記錄序列分割成為若干子串行分別進行直接插入排序,待整個序列中的記錄 基本有序 時,再對全體記錄進行依次直接插入排序。操作方法 選擇乙個增量序列t1,t2,tk,其中...