直接插入排序法介绍
直接插入排序(Straight Insertion Sort)的基本操作是:将一个元素插入到已经排好序的有序表中。比如有n个待排序的元素,把第一个元素当作有序表的第一个元素,后面的n-1个元素表示未排序的元素,排序过程中每次从未排序的元素中取出第一个元素,将它插入到有序表中的适当位置,使之成为新的有序表,重复n-1次可完成排序过程。
图解直接插入排序
第一次:将数组中的第一个元素当作a[0]当作有序表的第一个元素,剩下的元素当作无序元素
第二次:将数组中剩下元素中的第一个元素a[1]与有序表中的最右边的元素a[0]比较,a[1]大于a[0],插在a[0]的右边。
第三次:将数组中剩下元素中的第一个元素a[2]与有序表中的最右边的元素a[1]比较,a[2]小于a[1],继续与a[0]比较,a[2]小于a[0],将a[0]和a[1]往右移一位,将a[2]插入原本a[0]的位置。
依次类推,知道数组中的所有元素都变为有序。
直接插入排序实现
#include#define MAXSIZE 10 //用于排序的数组个数的最大值,可修改#define OK 1#define TRUE 1#define FALSE 0typedef int Status; //定义一个用于排序的顺序表结构typedef struct { int r[MAXSIZE]; int length; //用于记录顺序表的长度}SqList;//对顺序表做直接插入排序void InsertSort(SqList *L){ int i , j; for(i = 1; i <= L->length; i++){ //选择排序核心代码 if(L->r[i] < L->r[i - 1]){ int temp = L->r[i]; for(j = i - 1; L->r[j] > temp && j >= 0; j--){ L->r[j + 1] = L->r[j]; //元素后移 } L->r[j + 1] = temp; //将最小元素插入到正确的位置 } }}
算法复杂度和稳定性分析
最好的情况是序列本身是有序的,也就是没有移动的次数,只有比较的次数,时间复杂度是O(n)。最坏的情况是序列是倒序的,此时比较的时间复杂度为n2 /2。移动的时间复杂度为n2⁄ 2因此其时间复杂度是O(N2)。
如果排序记录是随机的,那么根据概率相同的原则,平均比较和移动次数约为n2/4次。从这里也看出,同样的 O(n2)时间复杂度,直接插入排序法比冒泡和简单选择排序的性能要好一些。
直接插入排序是稳定的算法,它满足稳定算法的定义:假设在数列中存在a[i]=a[j],若在排序之前,a[i]在a[j]前面;并且排序之后,a[i]仍然在a[j]前面。则这个排序算法是稳定的!