1.原理:插入排序就是每一步都将一个待排数据按其大小插入到已经排序的数据中的适当位置,直到全部插入完毕。
插入排序方法分直接插入排序和折半插入排序两种,这里只介绍直接插入排序,折半插入排序留到“查找”内容中进行。
2.基本思想:当插入第i个对象时,前面的R[1],R[2],…,R[i-1]已经排好序,此时,用R[i]的关键字与R[i-1], R[i-2],…的关键字顺序进行比较,找到插入位置即将R[i]插入,原来位置上对象向后顺移。
3.举例分析:原始数据为{21,25,49,25,16,08},刚开始未知有序序列,可以将数组的第一个数看做是有序的,第二个数就和第一个数比较,继续构成有序数组,就像滚雪球一样,有序数组越滚越大,最终整个数组都变成了一个有序数组
插入排序方法分直接插入排序和折半插入排序两种,这里只介绍直接插入排序,折半插入排序留到“查找”内容中进行。
2.基本思想:当插入第i个对象时,前面的R[1],R[2],…,R[i-1]已经排好序,此时,用R[i]的关键字与R[i-1], R[i-2],…的关键字顺序进行比较,找到插入位置即将R[i]插入,原来位置上对象向后顺移。
3.举例分析:原始数据为{21,25,49,25,16,08},刚开始未知有序序列,可以将数组的第一个数看做是有序的,第二个数就和第一个数比较,继续构成有序数组,就像滚雪球一样,有序数组越滚越大,最终整个数组都变成了一个有序数组
4.c++代码实现
#include<iostream>
using namespace std;
int a[100];
//交换函数,目的是交换数组中两个元素的位置
void swap(int a[],int i,int j)
{
int temp;
temp=a[i];
a[i]=a[j];
a[j]=temp;
}
/*插入排序
基本思想:首先将数组的第一个数a[0]看成是有序的,然后从第二个元素开始和它前面的元素进行比较,
如果比前面的某一个数大,就交换。由于前面的元素是有序的,所以就使有序元素的个数逐渐增大,直到等于n。*/
void Insert_Sort(int a[],int n)
{
int j;
for(int i=0;i<n-1;i++)
{
for(int j=i+1;j>0;j--){
if(a[j]<a[j-1]){ //此时把a[0]~a[j-1] 看成有序的,a[j]是待插入的
swap(a,j,j-1); //通过交换的方式把记录右移
}
}
}
}
int main()
{
int n;
cin>>n;
for(int i=0;i<n;i++)
cin>>a[i];
Insert_Sort(a,n);
for(int i=0;i<n;i++)
{
cout<<a[i]<<" ";
}
cout<<endl;
return 0;
}
/*
input
5
5 4 3 2 1
output
1 2 3 4 5
过程:
原始数据: 5 4 3 2 1
第一趟: 4 5 3 2 1
第二趟: 3 4 5 2 1
第三趟: 2 3 4 5 1
第四趟: 1 2 3 4 5
*/
5.算法分析当最好的情况,也就是排序本身是有序的,那么我们比较的次数是n-1次,没有移动的记录,时间复杂度是O(n).
当最坏的情况,即待排序表示逆序的情况,比如上述的{5,4,3,2,1},此时需要比较1+2+3+...n-1=(n-1)*(n-2)/2 ,而记录交换移动的次数也达到最大值 也是1+2+3+...n-1=(n-1)*(n-2)/2,所以直接插入排序的时间复杂度为O(n^2)。
直接插入排序比冒泡排序和简单选择排序的性能要好一些。
排序方法 | 平均情况 | 最好情况 | 最坏情况 | 辅助空间 | 稳定性 |
直接插入排序 | O(n^2) | O(n) | O(n^2) | O(1) | 稳定 |