插入排序小结
插入排序是一个O(n2)级别的算法,按照常理来说在系统级别的排序中是不会去用到这么“慢”的算法,但是它有也个性质——对==近乎有序==的序列进行排序速度非常快。这个神奇的性质可以放在很多排序算法中进行优化!
其算法思想很简单:
step1. 默认第一个元素有序,其余的元素无序。
如图 橙色为有序部分。灰色为无序部分。
step2. 从无序的序列中,取第一个元素插入到有序的序列中合适的位置。直到遍历结束。
temp 等于红色的框框里面的值。在黄色的有序中找到合适的插入位置。
void insertSort(int *Array,int n){
int temp;
int j;
for(int i=0;i<n;i++)
{
temp=Array[i];
for(j=i;j>0;j--) //因为比较的是Array[j-1]与temp的值,所以不能等于0
{
if(Array[j-1]>temp)
{
Array[j]=Array[j-1];
}//比temp大就往后移
else
{
break;//刚好这里
}
}
Array[j]=temp;//合适的位置插入进去即可
}
}
无论是算法的实现,还是思路都很简单。
下面看看其性能。
在十万的随机数
insert Sort:8.3768
mergeSort:0.024668
两种排序速度,是不可比拟的。
但是在近乎有序的数组中就变得不一样了。
在测试案例中,用一个十万的案例,随机交换了10个数字的位置产生一个近乎有序的数组排序。
insert Sort:0.003656
mergeSort:0.017127
这里可以发现,直接插入排序的速度是非常快的。
那这个性质可以用在哪里呢?会用到高级排序算法(指的是时间复杂度为O(nlogn)的算法)等其接近有序的时候使用直接插入排序能达到一些优化,在后续的博客中会体现出来。
希尔排序
希尔排序就是快速排序的一种变种,其思想跟直接插入排序很类似,其实就是设置一个 跨度 进行插入排序。
算法思想:
step1. 设置一个跨度d, 在待排序列中取出这个这个跨度的序列。
step2. 在这个取出来的序列上进行插入排序。
相同的颜色组成组合进行插入排序。
step3. 减少跨度重复step1 step2 step3
(注:d的寻找可以查一下相关书籍)
void shellSort(T arr[],int n){
int gap=0;
int i,j;
T temp;
while((gap*3+1)<n){
gap=gap*3+1;
}//寻找gap
while(gap>0)
{
for(i=gap;i<n;i++){
j=i-gap;
temp=arr[i];
while(j>=0&&arr[j]>temp)
{
arr[j+gap]=arr[j];
j=j-gap;
}
arr[j+gap]=temp;
}
gap=(gap-1)/3;
}
}
还是十万的数据测试
insert Sort:8.37982
Shell sort:0.033566
这速度不用多说!