1.直接插入排序:一种比较简单直观的排序算法,将待插入元素找到一个合适的位置并插入到前面的有序序列中。具体实现方法为:每次先用一个临时变量把带插入数据保存起来,然后逐个与前面有序集合里的元素进行比较,如果集合里的元素大于待插入元素(假设我们要从小到大进行排序),就将它向后移动一个单元,直到在有序集合里找到小于等于待插入元素的数时就将待插入元素放在这个数后面。
这里,我们依旧用画图的方法来更直观的理解一下插入排序:
由图中可以看出:每次排序都是将待排序元素插入到合适的位置并插入。所以我们可以这样来用代码实现插入排序,首先我把初始集合存放在一个数组中,然后用第一层for循环从前到后依次遍历整个数组,将元素一个一个插入到合适的位置,刚开始我们默认第一个元素是有序的,所以我们从第二个元素开始遍历数组。
3.实现代码如下:
void PrintSort(int arr[],size_t size)
{
size_t i=0;
for(; i<size; ++i)
{
printf(" %d ",arr[i]);
}
printf("\n");
}
void Swap(int *x,int *y)
{
*x^=*y;
*y^=*x;
*x^=*y;
}
void InsertSort(int arr[],size_t size)
{
int InsertValue;
size_t i=0;
int bound;
if(size<=1)
{
return;
}
for(i=1; i<size; ++i)
{
InsertValue=arr[i];
for(bound=i-1; bound>=0; --bound)
{
if(arr[bound]>InsertValue)
{
arr[bound+1]=arr[bound];
}
else
{
break;
}
}
arr[bound+1]=InsertValue;
printf("第%d次排序:",i);
PrintSort(arr,size);
}
}
int main()
{
int arr[]={77,5,43,26,9,16};
size_t size=sizeof(arr)/sizeof(arr[0]);
InsertSort(arr,size);
system("pause");
return 0;
}
运行结果为:
4.算法分析
时间复杂度:从前面的分析过程中可以看出,如果有n个数要进行排序,那么至少需要进行n-1趟循环,那么总共需要循环1+2+3+....+(n-1)=(n-1)/2次,所以插入排序的时间复杂度为O(n^2)。
空间复杂度:没有额外的空间开销,故空间复杂度为O(1),
稳定性:稳定,因为比较的时候,如果两个数的大小相等,则不需要移动,相同数的前后次序不会发生改变。
如图:
总结,在插入排序中,当元素个数非常少或者待排序区间基本有序的情况下,插入排序的·速度非常之快。详情请见希尔(shell)排序。