插入排序的基本思想是:每次将一个待排序的记录按其关键字的大小插入到前面已排好序的文件中的适当位置,直到全部记录插完为止。插入排序主要包括直接插入排序和希尔排序两种。
直接插入排序
直接插入排序是一种比较简单的排序方法,基本操作是:n个待排序的元素存在一个区域,在排序过程中逐渐分为两个部分,一个是有序区,一个是无序区,排序过程中,只需要每次从无序区中取出第一个元素,把它插入有序区的适当位置,使之成为新的有序区,依次这样经过n-1次插入后,无序区为空,有序区包含全部n个元素,至此排序完毕。直接插入算法是稳定的。
直接插入排序算法实现:
void InserSort (int arr[], int n) { int i,j; for(i=1; i<n; i++) { //将数据插入有序表 int tmp=arr[i]; //设置哨兵 if(tmp>arr[i-1]) { //将比当前数据大的元素依次向后移动 for(j=i-1; j>=0 && tmp>arr[j]; j--) arr[j+1]=arr[j]; arr[j+1]=tmp; } } }
直接插入排序动画演示:
希尔排序
希尔排序又称“缩小增量排序”,它是由希尔在1959年提出的。其基本思想是:先取定一个小于n的整数d作为第一个增量,把数组R中全部元素分成d1个组,所有下标距离为d的倍数的元素放在同一组中,即R[1],R[1+d1],R[1+2*d1]为第一组,R[2],R[2+d1],R[2+2*d1]为第二组,依次类推,接着在各组内进行直接插入排序,然后再取d2(d2<d1)为第二个增量,重复上述分组和排序,直到所取增量dt=1,把所有元素放在同一组中进行直接插入排序为止。希尔排序是不稳定的。
希尔排序算法实现:
void ShellSort (intarr[],int n) { int i, j, d; int tmp; d=n/2; //设置增量初值 while(d>0) { for(i=d; i<n;i++) //对所有相隔d的元素组进行直接插入排序 { tmp=arr[i]; j=i-d; while(j>n>=0 && tmp>arr[j]) //对每组中的数据进行排序 { arr[j+d]=arr[j]; j=j-d; } arr[j+d]=tmp; } d=d/2; } }
第一轮排序:
当d1=5时:上图中下标1和下标6为一组,下标2和下标7为同一组,依次类推,同色为一组 ,组内进行直接插入排序,从小到排到大,55<100顺序不变,22>11顺序对换,99>33顺序对换,77>66顺序对换,44<88顺序不变。
第二轮排序:
当d2=3时:上图中下标1、下标4、下标7和下标10为一组,依此类推,同色为一组,组内进行直接插入排序,从小排到大,第一组中55、66、22、88的重新排序应为22、55、66、88;第二组中11、44、99还是顺序不变;第三组33、100、77的重新排序应为33、77、100。
第三轮排序:
当d3=1时:上图所有元素为一组直接插入排序。