希尔排序增量研究
? ? ? ? 上一篇介紹了希爾排序,它又被稱為縮小增量排序,這就說(shuō)明了增量在希爾排序中的重要性。
? ? ? ? 本篇使用四組不同的增量,通過(guò)統(tǒng)計(jì)排序的比較次數(shù)、移動(dòng)次數(shù)、執(zhí)行時(shí)間,來(lái)討論不同的增量對(duì)希爾排序效率的影響。
? ? ? ? 選取的增量:h1=N/2, N/4, N/8,……,1(每次增量減半)
? ? ? ? ? ? ? ? ? ? ? ? ? ? ?h2=N/3, N/9, N/27,……,1(每次增量為原來(lái)的三分之一)
? ? ? ? ? ? ? ? ? ? ? ? ? ? ?h3=2?-1 (h=1,3,7,……)(增量為奇數(shù))
? ? ? ? ? ? ? ? ? ? ? ? ? ? ?h4=(3?-1)/2 (h=1,4,13,……)
? ? ? ? 1、保持序列元素個(gè)數(shù)不變
? ? ? ? 保持序列元素個(gè)數(shù)為1000000,每次隨機(jī)生成不同的序列,對(duì)四個(gè)增量分別做4組排序。
| 增量h | 比較次數(shù) | 移動(dòng)次數(shù) | 執(zhí)行時(shí)間(ms) | 平均時(shí)間(ms) |
| h1 | 70899317 | 53401514 | 390 | 409 |
| 71248646 | 53751082 | 437 | ||
| 63125216 | 45628028 | 406 | ||
| 65709200 | 48211399 | 406 | ||
| h2 | 58908538 | 47827463 | 328 | 367 |
| 57271566 | 46192005 | 360 | ||
| 58745050 | 47664214 | 422 | ||
| 58158118 | 47077871 | 359 | ||
| h3 | 63337835 | 45942623 | 391 | 434 |
| 62261484 | 44866301 | 422 | ||
| 64507400 | 47112762 | 485 | ||
| 65932139 | 48537533 | 438 | ||
| h4 | 67600938 | 56206667 | 359 | 398 |
| 62428374 | 51034112 | 390 | ||
| 67867685 | 56472626 | 453 | ||
| 63794589 | 52400141 | 391 |
? ? ? ??從測(cè)試的結(jié)果來(lái)看,當(dāng)序列元素個(gè)數(shù)相同時(shí),對(duì)四種增量分別用生成的四組隨機(jī)數(shù)排序時(shí),它們的比較次數(shù)、移動(dòng)次數(shù)以及執(zhí)行時(shí)間等參數(shù)差別不大。因此可以認(rèn)為對(duì)于待排序列的元素個(gè)數(shù)相同的情況下,基于以上四種增量的序列,希爾排序算法的時(shí)間復(fù)雜度差異不是很明顯,執(zhí)行效率差別不大。
? ? ? ? 2、序列的元素個(gè)數(shù)改變
? ? ? ? 使序列元素個(gè)數(shù)增加,分別取10000、100000、1000000、10000000,每次隨機(jī)生成不同的序列,對(duì)四個(gè)增量分別排序。
| 元素個(gè)數(shù) | 增量h | 比較次數(shù) | 移動(dòng)次數(shù) | 執(zhí)行時(shí)間(ms) |
| 10000 | h1 | 266301 | 151388 | 0 |
| h2 | 242150 | 171389 | 0 | |
| h3 | 237881 | 129346 | 15 | |
| h4 | 238686 | 167816 | 0 | |
| 100000 | h1 | 4270009 | 2820476 | 32 |
| h2 | 4174584 | 3267076 | 15 | |
| h3 | 3959590 | 2543037 | 32 | |
| h4 | 3867292 | 2941534 | 31 | |
| 1000000 | h1 | 66890878 | 49393622 | 422 |
| h2 | 59190877 | 48110274 | 360 | |
| h3 | 59872906 | 42478486 | 406 | |
| h4 | 62805422 | 51410564 | 375 | |
| 10000000 | h1 | 1035250229 | 820261049 | 5301 |
| h2 | 1167560154 | 1036812889 | 5532 | |
| h3 | 980127157 | 772150177 | 5294 | |
| h4 | 9659604955 | 854508598 | 5378 |
? ? ? ? 從測(cè)試結(jié)果可以看出,不同長(zhǎng)度的序列使用四個(gè)增量分別進(jìn)行排序時(shí),比較次數(shù)、移動(dòng)次數(shù)、排序時(shí)長(zhǎng)有一定差異。當(dāng)元素個(gè)數(shù)較少時(shí),增量為h2=N/3, N/9, N/27,……,1的希爾排序效率比其他增量略高;
當(dāng)元素個(gè)數(shù)較多時(shí),增量為h4=(3?-1)/2 (h=1,4,13,……)的希爾排序效率比其他增量略高。
? ? ? ? 綜上所述,希爾排序算法在不同增量下的執(zhí)行效率也不盡相同,增量是影響希爾排序效率的重要因素。遺憾的是,雖然有很多論文專門研究過(guò)不同的增量對(duì)希爾排序的影響,但都無(wú)法證明某個(gè)增量是最好的。因此在使用希爾排序時(shí),根據(jù)排序序列的大小,選取適當(dāng)?shù)脑隽繉?duì)提高排序效率很有幫助。
? ? ? ??參考代碼:以Java為例。
import java.util.Random;/** 希爾排序*/public class ShellSort {//增量h=N/2static long comp1 = 0; //比較次數(shù)static long exch1 = 0; //交換次數(shù)public static void sort1(int[] a) {int n = a.length; //序列長(zhǎng)度int h = n/2; //初始增量h為序列長(zhǎng)度的一半while (h >= 1) {for (int i = h; i < n; i++) {for (int j = i; j >= h; j -= h) {comp1++;if(a[j]<a[j-h]){int swap = a[j];a[j] = a[j-h];a[j-h] = swap;exch1++;}else{break;}}}h /= 2; //增量減半 }}//增量h=N/3static long comp2 = 0; //比較次數(shù)static long exch2 = 0; //交換次數(shù)public static void sort2(int[] a) {int n = a.length; //序列長(zhǎng)度int h = n/3; //初始增量h為序列長(zhǎng)度的三分之一while (h >= 1) {for (int i = h; i < n; i++) {for (int j = i; j >= h; j -= h) {comp2++;if(a[j]<a[j-h]){int swap = a[j];a[j] = a[j-h];a[j-h] = swap;exch2++;}else{break;}}}h /= 3; //增量減為三分之一 }}//增量h=2?-1 (h=1,3,7……)static long comp3 = 0; //比較次數(shù)static long exch3 = 0; //交換次數(shù)public static void sort3(int[] a) {int n = a.length; //序列長(zhǎng)度int h = 1;while (h < n/2) h = 2*h + 1;while (h >= 1) {for (int i = h; i < n; i++) {for (int j = i; j >= h; j -= h) {comp3++;if(a[j]<a[j-h]){int swap = a[j];a[j] = a[j-h];a[j-h] = swap;exch3++;}else{break;}}}h /= 2;}}//增量h=(3?-1)/2 (h=1,4,13……)static long comp4 = 0; //比較次數(shù)static long exch4 = 0; //交換次數(shù)public static void sort4(int[] a) {int n = a.length; //序列長(zhǎng)度int h = 1;while (h < n/3) h = 3*h + 1;while (h >= 1) {for (int i = h; i < n; i++) {for (int j = i; j >= h; j -= h) {comp4++;if(a[j]<a[j-h]){int swap = a[j];a[j] = a[j-h];a[j-h] = swap;exch4++;}else{break;}}}h /= 3;}}public static void main(String[] args) {Random random = new Random();int[] arg = new int[10000];for(int n=0;n<10000;n++){ //從[0-10000]中生成10000個(gè)隨機(jī)數(shù)arg[n] = random.nextInt(10000);}int[] arg1 = new int[arg.length];int[] arg2 = new int[arg.length];int[] arg3 = new int[arg.length];int[] arg4 = new int[arg.length];for(int n=0;n<arg.length;n++){ //將隨機(jī)生成的數(shù)組復(fù)制到4個(gè)數(shù)組中arg1[n] = arg[n];arg2[n] = arg[n];arg3[n] = arg[n];arg4[n] = arg[n];}//分別對(duì)4個(gè)元素相等的數(shù)組用4個(gè)不同增量排序long startTime1 = System.currentTimeMillis(); //獲取開(kāi)始時(shí)間 sort1(arg1);long endTime1 = System.currentTimeMillis(); //獲取結(jié)束時(shí)間long startTime2 = System.currentTimeMillis(); //獲取開(kāi)始時(shí)間 sort2(arg2);long endTime2 = System.currentTimeMillis(); //獲取結(jié)束時(shí)間long startTime3 = System.currentTimeMillis(); //獲取開(kāi)始時(shí)間 sort3(arg3);long endTime3 = System.currentTimeMillis(); //獲取結(jié)束時(shí)間long startTime4 = System.currentTimeMillis(); //獲取開(kāi)始時(shí)間 sort4(arg4);long endTime4 = System.currentTimeMillis(); //獲取結(jié)束時(shí)間System.out.println("數(shù)組長(zhǎng)度:"+arg.length);System.out.println("增量h=N/2的比較次數(shù): "+comp1+" 交換次數(shù):"+exch1+" 排序時(shí)長(zhǎng):"+(endTime1-startTime1)+"ms");System.out.println("增量h=N/3的比較次數(shù): "+comp2+" 交換次數(shù):"+exch2+" 排序時(shí)長(zhǎng):"+(endTime2-startTime2)+"ms");System.out.println("增量h=2?-1的比較次數(shù): "+comp3+" 交換次數(shù):"+exch3+" 排序時(shí)長(zhǎng):"+(endTime3-startTime3)+"ms");System.out.println("增量h=(3?-1)/2的比較次數(shù):"+comp4+" 交換次數(shù):"+exch4+" 排序時(shí)長(zhǎng):"+(endTime4-startTime4)+"ms");} }? ? ? ? ?執(zhí)行結(jié)果:
數(shù)組長(zhǎng)度:10000 增量h=N/2的比較次數(shù): 265465 交換次數(shù):150579 排序時(shí)長(zhǎng):0ms 增量h=N/3的比較次數(shù): 230360 交換次數(shù):159712 排序時(shí)長(zhǎng):0ms 增量h=2?-1的比較次數(shù): 238035 交換次數(shù):129679 排序時(shí)長(zhǎng):15ms 增量h=(3?-1)/2的比較次數(shù):227429 交換次數(shù):156614 排序時(shí)長(zhǎng):0ms?
? ? ? ? ?轉(zhuǎn)載請(qǐng)注明出處?http://www.cnblogs.com/Y-oung/p/7805984.html
? ? ? ??工作、學(xué)習(xí)、交流或有任何疑問(wèn),請(qǐng)聯(lián)系郵箱:yy1340128046@163.com
轉(zhuǎn)載于:https://www.cnblogs.com/Y-oung/p/7805984.html
總結(jié)
- 上一篇: 【前端】跨浏览器事件处理程序EventU
- 下一篇: numpy中的matrix与array的