插入排序是最简单的排序算法之一,它由 N-1 趟排序组成。对于 P=1 趟到 P=N-1趟,每一趟排序开始前都能保证从 0 到 P-1 位置上的元素是已经排好序的。在第 P 趟中,将位置 P上的元素向左移动到正确地位置上,当所有趟数执行完成后,整个数组就是有序的。
34 | 8 | 64 | 51 | 32 | 21 |
对于如上数组,数组下标从0开始,对于第 P 趟排序,将位置 P 上的元素与之前的所有元素进行比较,当发现有元素比 P 位置上的元素小时,将 P 位置的元素插入到该元素之后,就完成了一趟排序。
P=1 之后
8 | 34 | 64 | 51 | 32 | 21 |
P=2 之后
8 | 34 | 64 | 51 | 32 | 21 |
P=3 之后
8 | 34 | 51 | 64 | 32 | 21 |
P=4 之后
8 | 32 | 34 | 51 | 64 | 21 |
P=5 之后
8 | 21 | 32 | 34 | 51 | 64 |
到此就完成了排序,整个数组也变得有序。
插入排序的实现:
void insertion_sort(int* arr, int size){
for(int p=1;p<size;p++){//共执行size-1趟排序
int tmp=arr[p];//临时变量保存P位置的关键字
int i;
for(i=p;i>=1 && arr[i-1]>tmp;i--){//将P位置的关键字与它之前的关键字比较
arr[i]=arr[i-1];//如果i-1位置处的关键字大于P位置的关键字,则需要将i位置的元素后移
}
arr[i]=tmp;//跳出循环说明i-1位置的关键字小于P位置的关键字,则i位置就是P位置关键字正确的位置
}
}
插入排序最坏的时间复杂度是O(N^2),当输入序列是正序时,如果要将其逆序排列,就满足了插入排序的最坏时间界。当输入数据已经预先排好序,只有少部分元素需要排序,那么插入排序的时间复杂度将是O(N)。因为在程序中,除过不在正确位置的元素外,其他元素在判断 时就会跳出循环,所以循环不被执行,只有少量元素需要进行插入,由于循环只执行很少的次数,所以整体的时间复杂度为O(N)。