算法——希尔插入排序
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。
通过比较上面直接插入和希尔排序的核心代码。很容易的看出来,直接插入和希尔排序的相同点。他们简直就是一个。
分析过程:由于采用了C语言的写法(在VB,C#可能不会出现问题,没试过)编译的时候遇到了问题:
问题一:在c语言中,下面的两行代码是不一样的。
小编原先写的是第二行,所以就不断的程序崩溃,还好小编没有崩溃,经过无数次的验证,推理。终于找到了自己代码的小bug。得出一个非常严重的教训。
主要的判断,控制按优先级的顺序写,这样能防止一定的错误。就向方法的判null一样,把最优先的判断放在前面。
上面的两行代码,小数据量不会出错 <5000。大数据量就会崩溃了。为什么大数据量就会崩溃呢?
因为在C语言中是可以获取超出数组元素范围的值的,所以小数据量是还是可以获取array【-10】的值的。所以程序不崩。
当数据量大时,那么可能获取了array【-9999】的值。可能超出地址范围太大了。就崩溃了。
参考网址:希尔排序
希尔排序是插入排序的一种,它和其他的优化排序一样,例如堆排序,二路归并排序,是对原有基础排序方法的优化,把要排序的数列进行分组排序。每个组使用插入排序方法就行排序。然后在进行下一趟分组排序。
学习的难点: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】的值。可能超出地址范围太大了。就崩溃了。
参考网址:希尔排序
相关文章推荐
- c# 排序 算法 函数 冒泡 选择 插入 希尔
- Java实现的排序算法及比较 [冒泡,选择,插入,归并,希尔,快排]
- 数据结构-排序算法之插入排序(直接插入,二分插入,希尔,表插入)
- 无聊时总结总结算法之02排序(直接插入+希尔)
- C#算法----(二)插入排序 (转载)
- 数组排序总结(冒泡,选择,插入,希尔)
- 算法复习--插入排序
- 直接插入算法排序
- C语言实现 排序源程序(包括直接插入、希尔、冒泡、快速、简单选择、堆排序)
- 算法:插入排序
- 基础算法学习(一)__几种排序:选择、插入、冒泡和快排
- 常用算法总结之排序(七)---直接插入排序
- Java数组排序总结(冒泡,选择,插入,希尔)
- 数据结构与算法之C#插入排序
- Java数组排序(冒泡,选择,插入,希尔)
- python算法实践1-直接插入排序
- 算法-----插入排序
- 直接插入算法排序
- 插入排序(insertion sort)算法实现
- Java实现数组排序总结篇(冒泡,选择,插入,希尔)