日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

希尔排序(二)

發(fā)布時(shí)間:2025/3/15 编程问答 18 豆豆
生活随笔 收集整理的這篇文章主要介紹了 希尔排序(二) 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

另一種寫法

上一篇博文希爾排序(一)中的代碼是基于希爾排序的原理,“直譯”過來的。還有一種更簡(jiǎn)單的寫法:

void shellsort_2(int a[], int n) { int j, gap;for (gap = n / 2; gap > 0; gap /= 2) { #ifdef PRINT_PROCEDUREprintf("-------- gap = %d--------\n",gap);print_array(a, n,gap); #endiffor (j = gap; j < n; j++)//從數(shù)組第 gap個(gè)元素開始 ,直到 n-1 { if ( a[j - gap] > a[j] )//每個(gè)元素與自己組內(nèi)的數(shù)據(jù)進(jìn)行直接插入排序 { int temp = a[j]; int k = j - gap; while (k >= 0 && a[k] > temp) //&&優(yōu)先級(jí)更低 { a[k + gap] = a[k]; // a[k]向后移動(dòng) ,騰出一個(gè)空位k -= gap; }// 考察空位前面的元素a[k+gap] = temp; //插入 #ifdef PRINT_PROCEDUREprintf("[%d] insert to [%d]\n", j, k+gap);print_array(a, n,gap); #endif }}} }

對(duì)希爾排序的改進(jìn)

希爾排序的運(yùn)行時(shí)間依賴于增量序列的選擇。 舉個(gè)例子,如果使用 Shell 建議的序列,假使上一個(gè)增量為 4,那么當(dāng)前的增量就是 2。因?yàn)?是4的因子,所以對(duì)于上一輪已經(jīng)比較過的元素,這一輪會(huì)重復(fù)比較,這就造成了時(shí)間的浪費(fèi)。更好的增量序列選擇是增量序列中的任何2個(gè)元素都是互素的。目前已有學(xué)者提出了一些更有效的增量序列,這里僅展示其中的2個(gè)。

Hibbard (希巴德)序列

Hibbard(希巴德)序列:

1,3,7,...,2k?11,3,7,...,2k?1kk 為大于 00 的自然數(shù))

使用 Hibbard 增量的希爾排序,其最壞情形的運(yùn)行時(shí)間為 Θ(n3/2)Θ(n3/2)
其平均情形的運(yùn)行時(shí)間被認(rèn)為是 O(n5/4)O(n5/4)(基于模擬結(jié)果)。

Sedgewick (塞奇威克)序列

已知的最好的增量序列是由 Sedgewick(塞奇威克) 提出的: 1,5,19,41,109,....1,5,19,41,109,.... 這個(gè)序列中的項(xiàng)交替地取自以下2個(gè)序列:

1,19,109,505,2161,...,9?(4k?2k)+11,19,109,505,2161,...,9?(4k?2k)+1 (k=0,1,2,3,...)(k=0,1,2,3,...)

5,41,209,929,3905,...,2k+2(2k+2?3)+15,41,209,929,3905,...,2k+2(2k+2?3)+1 (k=0,1,2,3,...)(k=0,1,2,3,...)

使用 Hibbard 增量的希爾排序平均運(yùn)行時(shí)間猜測(cè)為O(n7/6)O(n7/6),最壞情形為O(n4/3)O(n4/3)

改進(jìn)后的C語言代碼

void shell_sort_improved(int A[], int N, int inc_seq[]) {int inc = 0; int max_inc_idx = 0; int i,j,k,tmp;while (inc_seq[ max_inc_idx + 1 ] < N) max_inc_idx++; //找到最大的且小于N的那個(gè)增量 for (i = max_inc_idx; i >= 0; --i){ inc = inc_seq[i]; #ifdef PRINT_PROCEDUREprintf("-------- gap = %d--------\n",inc); #endif for (j = inc; j < N; ++j) { if( A[j-inc] > A[j] ){tmp = A[j]; k = j - inc; while (k >= 0 && A[k] > tmp) { A[ k + inc ] = A[k]; // A[k]向后移動(dòng) inc個(gè)位置,騰出一個(gè)空位k -= inc; // 繼續(xù)考察空位前面的元素 } A[k + inc] = tmp; // tmp 插入到k的后面 #ifdef PRINT_PROCEDUREprintf("[%d] insert to [%d]\n", j, k+inc); #endif }} } }

最后一個(gè)參數(shù)是增量序列。

完整代碼及測(cè)試

#include <stdio.h> #include <stdlib.h> #include <time.h>#define PRINT_GAP 10 #define ARRAY_LEN 100void print_array(int a[], int len, int gap) // 用于打印數(shù)組 {for(int i=0; i<len; ++i){printf("[%2d]:%2d ", i, a[i]);if((i + 1) % gap == 0)printf("\n");}printf("\n\n"); }void shell_sort_improved(int A[], int N, int inc_seq[]) {int inc = 0; int max_inc_idx = 0; int i,j,k,tmp;while (inc_seq[ max_inc_idx + 1 ] < N) max_inc_idx++; //找到最大的且小于N的那個(gè)增量 for (i = max_inc_idx; i >= 0; --i){ inc = inc_seq[i]; #ifdef PRINT_PROCEDUREprintf("-------- gap = %d--------\n",inc); #endif for (j = inc; j < N; ++j) { if( A[j-inc] > A[j] ){tmp = A[j]; k = j - inc; while (k >= 0 && A[k] > tmp) { A[ k + inc ] = A[k]; // A[k]向后移動(dòng) inc個(gè)位置,騰出一個(gè)空位k -= inc; // 繼續(xù)考察空位前面的元素 } A[k + inc] = tmp; // tmp 插入到k的后面 #ifdef PRINT_PROCEDUREprintf("[%d] insert to [%d]\n", j, k+inc); #endif }} } } int main(void) {printf("\n");int array[ARRAY_LEN]; srand((unsigned int) time(NULL)); //設(shè)置隨機(jī)數(shù)種子// 產(chǎn)生100個(gè)隨機(jī)整數(shù),范圍在 [0, 100]for(int i=0; i<ARRAY_LEN; ++i){array[i] = rand() % 101;}print_array(array,sizeof(array)/sizeof(array[0]),PRINT_GAP);int Sedgewick_seq[] = {1, 5, 19, 41, 109};shell_sort_improved(array, sizeof(array)/sizeof(array[0]),Sedgewick_seq);print_array(array,sizeof(array)/sizeof(array[0]),PRINT_GAP);return 0; }

運(yùn)行結(jié)果如下圖:

【完】

參考資料

《數(shù)據(jù)結(jié)構(gòu)與算法分析(原書第2版)》(機(jī)械工業(yè)出版社,2004)

總結(jié)

以上是生活随笔為你收集整理的希尔排序(二)的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。