資料結構學習 shell排序的C語言實現

2022-05-04 04:00:07 字數 2064 閱讀 3602

shell排序:

這個排序的命名是來自發明者的名字,和排序的方法沒有字面上的聯絡。所以不要因為名字而感覺很難。在k&r的c程式語言中書中只用了幾行**很簡潔的實現了這個排序演算法。那就來看看這個排序是如何實現的。

原理:我們將所要排序的序列(大小為n)劃分成組,組的數量一般是可以用這個序列的大小的一半來定義(也就是d = n/2),然後不斷折半,而組的成員就是間隔為d的數分為一組。比如這邊有個長度為8的數字序列要去排序,那我們就可以先將這個序列分成d=4組的,每個組有兩個數,(這邊的4就是8的一半)。這四組就是(r1,r5),(r2,r6),(r3,r7),(r4,r8).然後就是組內比較,如果前者大,交換他們的位置。以次類推。

編寫程式時就是將我們所取的數和與他間隔為d大小的位置上的數比較。

這邊第一次組的數量是4,那麼就是將第乙個數和他間隔為4的數比較。當第一次排序後,我們將這個間隔縮小,就是拿上一次組數d折半。那麼這次的組就只有2個了。每個組有4個數.同樣是和上面一樣,間隔為d=2的位置上的數比較(實際上操作是這樣的,但是我們可以認為他們已經是在乙個組裡面了,就可以說成組內比較)。我們知道d最後會變成1的,那會兒就是相鄰的兩個數比較,所有的數字都會放在正確的位置上的。原理基本是這樣的。

實現:我們知道了原理,那就用自己熟悉的語言將其編寫出來,我們這邊是用的c語言,將其編寫出來的。

我們按照我們上述的原理將其一步一步的實現下:

1

//函式的引數包含兩個,乙個是要排序的陣列,乙個是陣列的大小2//

函式不使用額外的空間,只用到陣列本身。這就要求陣列在輸入時候保留出3//

r[0],r[0]就相當是乙個temp。用於互換兩個數時的乙個臨時數。

4void shellsort(int r,intn)5

23//

這邊就是對應著上面的j-=d,如果上面的while執行了,j

24//

位置的值已經給了j+d位置了,那麼j+d的值也要給j位置,互換

25//

這就要求下標必須是對應的。所以要將j-d才能滿足這邊是r[j]

26//

如果while沒有執行,那麼還將原來的r[i]的值放到原來位置上

27 r[j+d] = r[0

];28}29

//d減半

30 d/=2;31

}32 }

上面就是按照所述的原理實現的,**也不是很多,但是看上去有點亂,那麼能不能改進點呢?下面就來了啊。

精簡:我們一般在保證程式的可讀上,將程式變得很精巧。這也是k&r的乙個思想把。我們知道while和for在一定的情況下是可以替代的。所以我們可以將上述的程式,變得更為緊湊些,我們用三個for迴圈就可以了。下面是精簡後的實現:

1 #include2

3#define n 100

4void shellsort(int *,int);5

6int main(void)7

1920

shellsort(v,n);

2122 printf("

shell排序後:");

23for(i =0;i < n;i++)

2427

28 printf("\n"

);29

return0;

30}3132

void shellsort(int v,int

n)33

44 }

這邊我給出了乙個完整的程式,不過我們只看函式的實現。上面的函式中,第乙個for迴圈控制的是被比較數之間的間隔,也可以說是分組的依據。中間的迴圈是控制元素移動位置的。最後乙個迴圈就是組內的比較,如果順序不對就交換位置。將第乙個函式裡面的while整合成了for,這樣看起來程式很精簡,我們在理解上可能會有些卡殼,如果熟悉while和for之間轉換的話就會好很多。

補充:

for(表示式1;表示式2;表示式3)

語句;等價於while的為:

表示式1;

while(表示式2)

資料結構學習筆記 排序

排序 就是要整理表中的元素,使之按關鍵字遞增 或遞減 有序排列。如果待排序的表中,存在有多個關鍵字相同的元素,經過排序後這些具有相同關鍵字的元素之間的相對 次序保持不變,則稱這種 排序演算法是穩定的。在排序過程中,若整個表都是放在記憶體中處理,排序時不涉及資料的內 外存交換,則稱之為 內排序 反之,...

資料結構學習 氣泡排序

演算法描述 氣泡排序的思想是在每趟交換的過程,比較相鄰的兩個元素,將值大的放在右邊,即將當前比較過程中的最大值移動到右邊,然後將比較過程的最大索引減1,繼續第二趟排序,將剩餘元素中的最大值移動到右邊,依次類推,直到發現有一趟比較過程中沒有發生交換,則說明陣列已經排好序了。演算法時間複雜度 最好情況 ...

資料結構學習 希爾排序

演算法描述 希爾排序是插入排序的一種改進,主要是為了解決當較小的資料大都出現在陣列後面時導致的移動次數明顯增多的問題,思想是使用乙個不斷縮小的增量gap將陣列元素分組,在每個分組內部先進行插入排序,當gap減少到1時整個陣列元素分在一組,最後進行一次插入排序,整個排序過程結束。演算法時間複雜度 最好...