排序的基本概念
- 排序的稳定性:经过排序后的数列中具有相同关键字的元素之间的相对次序保持不变,称这种排序方法是稳定的。
- 内排序:整个表都是放在内存中处理,排序时不涉及内外数据的交换
- 外排序:排序过程中需要进行内、外数据的交换
插入排序的基本思想
每次将一个带排序的元素,按其关键字的大小插入到已经排好序的子表的适当位置,直到全部元素插入完成为止。
直接插入排序思想
对于一个数组:R[0……n-1],看成2部分,一部分有序,一部分无序。起始时有序的为R[0],无序的为R[1……n-1],每一次从无序列中取出最左边元素,插入到有序列中合适的位置。
代码实现
#include <iostream>
using namespace std;
void insertSort(int a[],int n){
int tmp,j;
for(int i=1;i<n;i++){//遍历无序部分
tmp=a[i];
j=i-1;
//将无序最左侧的元素和有序部分进行比较
while(j>=0&&tmp<a[j]){
//将有序部分元素大于a[i]的向后移
a[j+1]=a[j];
j--;
}
a[j+1]=tmp;//把带插入元素放到合适的位置
}
}
int main()
{
int a[]={9,8,7,6,5,4,3,2,1,0};
insertSort(a,10);
for(int i=0;i<10;i++){
cout << a[i] << endl;
}
return 0;
}
算法分析
时间复杂度:
正序(关键字递增有序):不进入内循环。外循环进行 n-1趟,也即是比较了n-1次(tmp<a[j]);每趟进行2次赋值(tmp=a[i];a[j+1]=tmp;)
正序的关键字比较次数最小和元素移动最小次数
反序(关键字递减):关键字比较R[0……i-1]都学要比较就是i次;内循环移动R[0……i-1]都要后移,再加上外面(tmp=a[i];a[j+1]=tmp;)共有i+2。
正序的关键字比较次数最大和元素移动最大次数
对于R[i](1<=i<=n-1)插入到有序区R[0……i-1]中,平均比较次数i/2;平均移动数i/2+2。所以平均时间复杂度:
空间复杂度:
只是用了i,j,tmp,与问题规模无关,空间复杂度为O(1)