排序1:插入排序(以从小到大排序为例)
重点关注各种排序时间复杂度,空间复杂度,已经有序的时间空间复杂度,稳定性的对比
1.1原理:
(举例说明更清晰)
设原数据: 5 9 4 7 2
1.2代码
void InsertSort(int *arr,int len)
{
int tmp;
int i;
int j;
//从前往后找位置
for( i=1;i<len;i++)
{
tmp=arr[i];
for(j=0;j<i;j++)
{
if(arr[j]>tmp)
{
break;
}
//移动后面数据
for(int k=i-1;k>=j;k--)
{
arr[k+1] = arr[k];
}
//插入数据
arr[j] = tmp;
}
}
1.3评价
①.时间复杂度:O(n^2),空间复杂度O(1)
②当原数据本身有序时,该排序时间复杂度O(n^2),空间复杂度O(1)
③稳定性:稳定性指的是原数据中若有相同数据,排序后相同数据的顺序不变(没有交换位置)本排序方法不稳定
1.4根据评价改进
(改进后即为插入排序的算法,写改进前的算法,一方面是为了理解插入排序法的来源,另一方面是为了理解为什么比较数据需要从后往前,因为我们常用思维是从前往后比较)
找位置比较时从前往后改为从后往前 ,时间复杂度可提升至O(n)而且从后往前,在比较大小同时可以移动数据,代码改为:
//从后往前找位置同时移动数据
for( i=1;i<len;i++)
{
Tmp=arr[i];
for(j=i-1;j>=0;j--)
{
if(arr[j]<=tmp)
{
break;
}
else//否则arr[j]>tmp需要移动数据
{
arr[j+1]=arr[j];
}
//插入数据
arr[j+1]=tmp;
}
}
1.5改进后评价(对插入排序法的评价)
①时间复杂度:o(n^2),空间复杂度o(1)
②已经有序。时间复杂度:o(n),空间复杂度o(1),则插入排序越有序
③本算法稳定。
注1:稳定性是指本排序方法可以达到稳定,而不是个人因代码写得有差异导致没达到稳定状态。
如:以上代码If(arr[j]<=tmp写为If(arr[j]<tmp),会导致不稳定。
注2:判断稳定性的根本方法为:是否有跳跃式的交换数据,因为跳跃交换无法确定相同关键字是否交换。可能相同的数字被跳过去也可能没跳。如: 5 4 2 7将5和2交换为跳跃式交换。