排序算法(2)

5.希尔排序(Shell)

void shellsort1(int num[], const int len)

{

    if (len <= 1) return;



    int i, j, k, dlen, temp;



    for (dlen = len / 2; dlen > 0; dlen /= 2) //确定步长

    {

        for (i = 0; i < dlen; i++)

        {

            for (j = i + dlen; j < len; j += dlen)

            {

                temp = num[j];

                k = j - dlen;

                while (k >= 0 && num[k] > temp)

                {

                    num[k + dlen] = num[k];

                    k -= dlen;

                }

                num[k + dlen] = temp;

            }

        }

    }

}



void shellsort2(int num[], const int len)

{

    int i, j, dlen, temp;



    for (dlen = len / 2; dlen > 0; dlen /= 2)

    {

        for ( i = dlen; i < len; i++) //从第二序列开始,前面为有序区

        {

            if (num[i] < num[i - dlen])

            {

                temp = num[i];

                j = i - dlen;

                while (j >= 0 && num[j] > temp)

                {

                    num[j + dlen] = num[j];

                    j -= dlen;

                }

                num[j + dlen] = temp;

            }

        }

    }

}

一行两种写法都可以,但是后者比较便于理解和书写。

希尔排序时间复杂度为O(nlogn),不过无需额外开辟空间,属于不稳定排序。

希尔排序的时间性能优于直接插入排序,原因如下:

(1)当文件初态基本有序时,直接插入排序所需的比较和移动次数较多;

(2)当n值较小时,n和n^2的差别也较小,即直接插入排序的最好时间复杂度O(n)和最坏时间复杂度O(n^2)差别不大。

基于以上两点,在希尔排序开始时增量较大,分组比较多,每组的记录数目较少,故各组内直接插入排序较快。后来增量逐渐缩小,分组数目逐渐较少,各组记录数目逐渐增多,但由于文件基本接近有序状态,所以新的排序过程较快。

你可能感兴趣的:(排序算法)