插入排序
思想
把待排序的纪录按其关键码值的大小逐个插入到一个已经排好序的有序序列中,直到所有的纪录插入完为止,得到一个新的有序序列。
设无序数组为a[0…n-1]。
1. 初始时,a[0]自成1个有序区,无序区为a[1..n-1]。
2. 令i=1,将a[i]插入当前的有序区a[0…i-1]中形成a[0…i]的有序区间。
3. i++并重复第二步直到i==n-1,排序完成。
一趟直接插入排序方法
具体做法:
将待插入记录 a[i]的关键字从右向左依次与有序区中记录 a[j]的关键字进行比较:
1. 若 a[j]的关键字大于 a[i]的关键字,则将 a[j]后移一个位置;
2. 若 a[j]的关键字小于或等于 a[i]的关键字,则查找过程结束,j+1 即为 a[i]的插入位置。
关键字比a[i]的关键字大的记录均已后移,所以 j+1 的位置已经腾空,只要将 a[i] 直接插入此位置即可完成一趟直接插入排序。
例如待排序数组a[0]=8,a[1]=5,a[2]=10,a[3]=12,a[4]=7,a[5]=6
第一趟:a[0]=8,有序,a[1...5]无序。
第二趟:temp=5,a[1]=5 < a[0]=8, 8往后移一位,a[1]=8,a[0]=5,a[0...1]有序,a[2...5]无序。
第三、四趟:a[2]=10 > a[1]=8,a[3]=12 > a[2]=10,有序无须移动,a[4...5]无序。
第五趟:temp=7,a[4]=7 < a[3]=12,12往后移一位,a[4]=12,依次类推...直到a[0]=5 < temp,即a[1]=7。
第六趟类比第五趟,可以得到6插入位置为a[1]=6。排序完成。
代码
#include <stdio.h>
//直接插入排序
void insertSort(int *arr, int n)
{
if (arr == NULL || n == 0)
{
return;
}
//第一个数肯定是有序的,从第二个数开始遍历
int i;
for (i = 1; i < n; ++i)
{
//补全代码
int temp = arr[i];
int j;
for( j=i-1;j>=0&&temp<arr[j];--j)//当要插入的数小于前面的数时
{
arr[j+1] = arr[j];//将前面的数往后移
}
arr[j+1] = temp;//不满足for条件时直接插入原位置
}
}
int main(){
int arr[10] = {8, 5, 10, 12, 7, 6, 15, 9, 11, 3};
insertSort(arr,10);
int i;
for (i = 0; i < 10; ++i) {
printf("%d ",arr[i]);
}
printf("\n");
return 0;
}