您的位置:首页 > 其它

算法——希尔插入排序

2016-09-28 19:48 239 查看
    上篇说到插入排序,现在来说下插入排序的优化——希尔排序。

    希尔排序是插入排序的一种,它和其他的优化排序一样,例如堆排序,二路归并排序,是对原有基础排序方法的优化,把要排序的数列进行分组排序。每个组使用插入排序方法就行排序。然后在进行下一趟分组排序。

    学习的难点:1、怎么分组?2、分组的重点是哪?3、怎么排序?

    其实学好插入排序后,希尔排序就好理解了。

    一、减半增量排序。选取下标为i,i+d,i+2d......的数组元素为一组。即i+2d的前一位置为i+d,i+d的前一位置为i。类似基础的直接插入排序。

   二、对数组按组进行直接插入排序。注意每组的前一位置。

   三、直到d=1时,进行最后一次排序。如果d=1,就相当与把数组分为了一组,这就和直接插入排序一模一样了。整个排序也就到此为止了。

   

    看数组元素在数组位置的移动

    


    因为直接插入元素的增量为1,而希尔排序的增量为d,所以这里的上图数据移动位置为依次为d。

    

<span style="font-size:24px;"><span style="font-family:KaiTi_GB2312;font-size:18px;">#include <stdio.h>
#include <stdlib.h>

//希尔排序
void shell(int array[],int n,int dk )
{

int i,j,temp;
//插入排序核心代码
//    for (i=1;i<10;i++)
//        {
//            temp=array[i];
//            j=i-1;
//                while(temp<array[j]&&j>0)
//                {
//                    array[j+1]=array[j];
//                    j--;
//                }
//                if(j!=i-1)
//                    array[j]=temp;
//
//        }
//希尔排序核心代码
for (i=dk;i<n;i++)
{
temp=array[i]; //temp为临时变量
j=i-dk;
while( j>=0 && j<n && temp<array[j])  //要确保下标j不超过长度n,不小于0
{
array[j+dk]=array[j];   //j位置的后一位置为j+dk,dk为增量
j-=dk;
}
if(j!=i-dk)
{
array[j+dk]=temp;
}
}

}
void shellpaixu()
{
int i,j,k;
int array[10000];
for(i=0;i<10000;i++)
array[i]=10000-i;
for(i=10000/2;i>=1;i=i/2)
shell(array,10000,i);
for(i=0;i<10000;i++)
printf("%d,",array[i]);
}

void main()
{

shellpaixu();

}

</span></span>


    通过比较上面直接插入和希尔排序的核心代码。很容易的看出来,直接插入和希尔排序的相同点。他们简直就是一个。

分析过程:由于采用了C语言的写法(在VB,C#可能不会出现问题,没试过)编译的时候遇到了问题:

   
问题一:在c语言中,下面的两行代码是不一样的。

<span style="font-size:24px;">while( j>=0 && temp<array[j] ) //先判断下标是否越界,然后比较
while( temp<array[j] && j>=0)  先比较,然后判断下标是否越界</span>




     小编原先写的是第二行,所以就不断的程序崩溃,还好小编没有崩溃,经过无数次的验证,推理。终于找到了自己代码的小bug。得出一个非常严重的教训。

     主要的判断,控制按优先级的顺序写,这样能防止一定的错误。就向方法的判null一样,把最优先的判断放在前面。

    上面的两行代码,小数据量不会出错 <5000。大数据量就会崩溃了。为什么大数据量就会崩溃呢?

    因为在C语言中是可以获取超出数组元素范围的值的,所以小数据量是还是可以获取array【-10】的值的。所以程序不崩。

   当数据量大时,那么可能获取了array【-9999】的值。可能超出地址范围太大了。就崩溃了。

参考网址:希尔排序

    

    

    
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: