1. 程式人生 > 實用技巧 >資料結構C語言實現----希爾排序

資料結構C語言實現----希爾排序

希爾排序

  這方法太噁心了,可以和冒泡、直插、選擇進行組合,就是希爾排序裡要內嵌其他排序,可是再希爾排序裡實現其他排序,要進行一些腦筋急轉彎的改變,所以剛學的時候肝了一天才弄明白;

  

  大體說一說思路吧,以內嵌氣泡排序為例

  加入這裡有一個無序數字串:9876543210

  我們要給他分組,一般會把總長除以二作為第一次的組數,10\2 = 5

  所以我們把他分為如下圖所示的兩個一組共五組:

  

  

  五組分別是(9 4)(8 3)(7 2)(6 1)(5 0)

  對這五組分別進行氣泡排序

  我們可以設定這樣一個迭代來執行五次氣泡排序:

  

for(i = 1  , i < gap , i++)
{
    /*
    氣泡排序
    */
}

  接下里,gap/2=2

  又分為如下的兩組:

  

  這兩組分別為(9 7 5 3 1)(8 6 4 2 0)

  同樣我們用上面的迭代,對兩組分別做氣泡排序

  因為分組後,每個子序列資料之間都隔著gap個距離,所以內嵌的排序要做出改動(以冒泡為例)

  以在分為兩組的情況下舉例:

  兩個元素兩個元素的比較,比如這一組第一個元素在陣列中下標為j,那麼這一組中第二個元素在陣列中的下標為j+gap

  氣泡排序結束時要保證這一組的元素是有序的,所以只有在對這一組元素進行氣泡排序時元素之間都不進行交換了就可以證明這組數有序了

  就可以結束這一組的氣泡排序,進入下一組的氣泡排序

執行結果:

  

原始碼如下:

#include<stdio.h>
typedef int keytype;
//希爾排序
void shellsort(keytype k[] , int n)
{
    int gap = n;
    int j;
    int flag = 1;
    while (gap > 1)
    {
        gap = gap/2;
        for (size_t i = 1; i <= gap; i++)//分為gap組,每組第一個元素為i
        {
            //子序列應用氣泡排序
            do
            {
                flag=0;
                for (j = i; j <= n-gap; j+=gap)
                {
                    if (k[j] > k[j+gap])
                    {
                        k[0] = k[j];
                        k[j] = k[j+gap];
                        k[j+gap] = k[0];
                        flag = 1;
                    }
                }
            } while (flag==1);   
        }
    }
}
#define MAX 100
int main()
{
    //讀取一串數字
    printf("請輸入一串無序數字:");
    int c;
    int n = 1;
    keytype k[MAX];
    while ((c = getchar())!='\n')
    {
        k[n++] = c-'0';
    }
    if (c == '\n')
    {
        k[n] = '\0';
    }
    //氣泡排序
    shellsort(k,n-1);
    printf("這串數字從小到大為:");
    for (size_t i = 1; i <= n-1; i++)
    {
        printf("%d",k[i]);
    }
    return 0;
}