希爾排序的C語言實現(1)

來源:互聯網
上載者:User

 

代碼

#include <stdio.h>
#include <stdlib.h>

int initialStep(int size);
void sort(int array[], int from, int end);
void insertSort(int array[], int groupIndex, int step, int end);
void move(int array[], int startIndex, int endIndex, int step);
void PrintArray(const char* strMsg,int array[],int nLength);

int main(int argc, char *argv[])
{
  int data[13]={8,5,4,6,13,7,1,9,12,11,3,10,2};
  sort(data,0,12);
  PrintArray("Shell Sort:",data,13);
  
  system("PAUSE");    
  return 0;
}

/**  
 * 根據數組長度求初始步長  
 *   
 * 我們選擇步長的公式為:2^k-1,2^(k-1)-1,...,15,7,3,1 ,其中2^k 減一即為該步長序列,k  
 * 為排序輪次  
 *   
 * 初始步長:step = 2^k-1   
 * 初始步長約束條件:step < len - 1 初始步長的值要小於數組長度還要減一的值(因  
 * 為第一輪分組時盡量不要分為一組,除非數組本身的長度就小於等於4)  
 *   
 * 由上面兩個關係試可以得知:2^k - 1 < len - 1 關係式,其中k為輪次,如果把 2^k 表 達式  
 * 轉換成 step 運算式,則 2^k-1 可使用 (step + 1)*2-1 替換(因為 step+1 相當於第k-1  
 * 輪的步長,所以在 step+1 基礎上乘以 2 就相當於 2^k 了),即步長與數組長度的關係不等式為  
 * (step + 1)*2 - 1 < len -1  
 *   
 * @param len 數組長度  
 * @return  
 */  
int initialStep(int size) {   
    /*  
     * 初始值設定為步長公式中的最小步長,從最小步長推匯出最長初始步長值,即按照以下公式來推:  
     * 1,3,7,15,...,2^(k-1)-1,2^k-1  
     * 如果數組長度小於等於4時,步長為1,即長度小於等於4的數組不且分組,此時直接退化為直接插  
     * 入排序  
     */  
    int step = 1;   

    //試探下一個步長是否滿足條件,如果滿足條件,則步長置為下一步長   
    while ((step + 1) * 2 - 1 < size - 1) 
    {   
       step = (step + 1) * 2 - 1;   
    }   

    printf("初始步長 - %d\n",step);   
    return step;   
}

/**  
  * 排序演算法的實現,對數組中指定的元素進行排序  
  * @param array 待排序的數組  
  * @param from 從哪裡開始排序  
  * @param end 排到哪裡  
  * @param c 比較子  
  */  
void sort(int array[], int from, int end) {
    int groupIndex;  
    //初始步長,實質為每輪的分組數   
    int step = initialStep(end - from + 1);   

    //第一層迴圈是對排序輪次進行迴圈。(step + 1) / 2 - 1 為下一輪步長值   
    for (; step >= 1; step = (step + 1) / 2 - 1) {   
        //對每輪裡的每個分組進行迴圈   
        for (groupIndex = 0; groupIndex < step; groupIndex++) {   

            //對每組進行直接插入排序   
            insertSort(array, groupIndex, step, end);   
        }   
    }   
}   

/**  
 * 直接插入排序實現  
 * @param array 待排序數組  
 * @param groupIndex 對每輪的哪一組進行排序  
 * @param step 步長
 * @param end 整個數組要排哪個元素止  
 * @param c 比較子  
 */  
void insertSort(int array[], int groupIndex, int step, int end) {
    int i,j;   
    int startIndex = groupIndex;//從哪裡開始排序   
    int endIndex = startIndex;  //排到哪裡   
    /*  
     * 排到哪裡需要計算得到,從開始排序元素開始,以step步長,可求得下一元素是否在數組範圍內,  
     * 如果在數組範圍內,則繼續迴圈,直到索引超現數組範圍  
     */  
    while ((endIndex + step) <= end) {   
        endIndex += step;   
    }   

    // i為每小組裡的第二個元素開始   
    for (i = groupIndex + step; i <= end; i += step) {   
        for (j = groupIndex; j < i; j += step) {   
            int insertedElem = array[i];   
            //從有序數組中最一個元素開始尋找第一個大於待插入的元素   
            if (array[j]>= insertedElem) {   
                //找到插入點後,從插入點開始向後所有元素後移一位   
                move(array, j, i - step, step);                   
                array[j] = insertedElem;   
                break;   
            }   
        }   
    }   
}
 

/**  
* 以指定的步長將數組元素後移,步長指定每個元素間的間隔  
* @param array 待排序數組  
* @param startIndex 從哪裡開始移  
* @param endIndex 到哪個元素止  
* @param step 步長  
*/ 
void move(int array[], int startIndex, int endIndex, int step) {
     int i;   
     for (i = endIndex; i >= startIndex; i -= step) {   
        array[i + step] = array[i];   
     }   
}

void PrintArray(const char* strMsg,int array[],int nLength)
{
     int i;
     printf("%s",strMsg);
     for(i=0;i<nLength;i++)
     {
        printf("%d ",array[i]);
     }
     printf("\n");
}

 

以上代碼主要修改自:http://www.javaeye.com/topic/547734 
                            http://www.javaeye.com/topic/547735
其它參考資料:
http://www.cnblogs.com/ziyifly/archive/2008/09/10/1288499.html
http://www.java2000.net/p11750
http://mintelong.javaeye.com/blog/467833
http://student.zjzk.cn/course_ware/data_structure/web/paixu/paixu8.2.2.1.htm
http://www.cnblogs.com/hualei/archive/2010/08/17/1801850.html

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.