假设数组为 a[0***n-1].
直接插入排序
假设待排序的关键字放在顺序表 a[0***n-1]中. 初始时, a [0] 自成一个有序区, 无序区为a[1***n-1]. 从i=1起直至 i=n-1为止, 依次将a[i] 插入 有序区a[0***i-1]中,
最后生成含n个记录的有序区.
第i趟直接插入排序的基本操作是 将当前无序区的第一个记录 a[i], 从后往前依次与有序区中记录a[j] (j=i-1, i-2, ..., 0) 进行比较, 若a[i]小于a[j], 则将a[j]后移一个位置; 若大于或等于, 则查找过程结束. j+1即为 a[i]的插入位置. 关键字比a[i]大的记录均已后移, 所以j+1的位置已经腾空, 只要将a[i]直接插入此位置即可完成第i趟直接插入排序 . 使a[0***i]变为新的有序区.
例: [0] [1] [2] [3] [4] [5] [6]
79 43 28 81 12 15 31
[0] [1] [2] [3] [4] [5] [6]
<79> 43 28 81 12 15 31
有序区 无序区
第一趟排序:
寻找元素a[1]排序后的位置, 即a[1]中的43与有序区中的元素一一比较, 直到大于或等于有序区的某个元素为止, 因为比较到的第一个元素a[0]为79, 43小于79, 所以 79 后移一位, 空出下标为 0 的单元, 即为元素 a[1] 排序后的位置。
<43 79> 28 81 12 15 31
第二趟排序:
a[2] 与 有序区的元素一一比较, 28小于 79, 所以79后移一位, 28小于 43, 所以43后移一位, 空出下标为0的单元, 即为a[2]插入的位置。
<28 43 79> 81 12 15 31
之后的就不一一列出来了。
总的过程如下:尖括号内表示的是有序区
[0] [1] [2] [3] [4] [5] [6]
<79> 43 28 81 12 15 31
排序过程:
<43 79> 28 81 12 15 31
<28 43 79> 81 12 15 31
<28 43 79 81 > 12 15 31
<12 28 43 79 81> 15 31
<12 15 28 43 79 81> 31
<12 15 28 31 43 79 81>
直接插入排序是稳定的排序方法。时间复杂度是O(n2).
c++代码:
void Insertsort(int a[], int n)
{
int i=1, j;
for( ; i<n; i++)
if( a[i] < a[i-1] )
{
int tmp =a[i];
for(j=i-1; j>=0 && a[j]>tmp ; j-- )
a[j+1] = a[j] ;
a[j+1] =tmp;
}
}
#include <iostream>
using namespace std;
const int MAX=7;
void insertsort(int a[], int n)
{
int i=1, j;
for( ; i<n; i++)
if( a[i] < a[i-1] )
{
int tmp =a[i];
for(j=i-1; j>=0 && a[j]>tmp ; j-- )
a[j+1] = a[j] ;
a[j+1] =tmp;
}
}
int main()
{
int A[MAX] = { 79,43,28,81,12,15,31};
insertsort(A, 7);
for( int i=0; i<7; i++)
{
cout<<A[i]<<" ";
}
cout<<endl;
return 0;
}
运行结果: