十大排序算法——插入排序(未完结)
一、直接插入排序
1.算法思想
在待排序的元素中,假设前n-1个元素已有序,现将第n个元素插入到前面已经排好的序列中,使得前n个元素有序。按照此法对所有元素进行直接插入,直到整个序列有序。
但我们并不能确定待排元素中究竟哪一部分是有序的,所以我们一开始只能认为第一个元素是有序的,依次将其后面的元素插入到这个有序序列中来,直到整个序列有序为止。
动态演示如下图所示:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-JU7tpxW3-1633624573155)(E:\CSDN\十大排序算法\3.插入排序.gif)]
2.代码实现
void insertSort(int *list,int length){
//记录本次循环过程中待查入的值
int temp=0;
//记录本次循环中有序序列的最后一个元素的下标
int end=0;
for(int i=0;i<length-1;i++){
temp=list[i+1];
end=i;
//对待插入的元素在有序片段进行单次查找
while(end>=0){
if (temp<list[end]) //仅当待排序数小于时才进行有序片段后移操作,保证排序算法的稳定性
{
list[end+1]=list[end]; //先将end元素所指的元素后移,再执行end--;
end--;
}
else
{
break; //end所指的元素比待插入的数小,跳出循环;
}
}
//把待插入的元素放在比插入数小的数的后面
list[end+1]=temp;
//执行此处的两种情况
//1.temp比有序序列中的某一个元素大执行break操作再执行此处的代码
//2.temp比有序序列的所有元素都小,此时end=-1,执行上述语句temp的值插入list[0];
}
}
3.算法时空复杂度分析
时间复杂度:最坏情况下为O(N*N),此时待排序列为逆序,或者说接近逆序
最好情况下为O(N),此时待排序列为升序,或者说接近升序。
空间复杂度:O(1)
二、折半插入排序
1.算法思想
折半插入排序与直接插入排序的思想相同的地方是,依次从第二个元素开始,通过和有序序列的元素进行比较,从而将待排序的数值插入有序序列的合适位置。
折半插入排序与直接插入排序思想所不同的地方是,在将待排序数值插入有序序列时折半插入排序采用折半查找的思想,在有序序列中通过折半查找,找到合适插入的位置。
2.代码实现
void binaryInsertSort(int* list,int length){
int left,right,mid;
int temp;
int j,i;
//此时默认第一个数组的第一个元素是有序的,所以从第二个元素开始进行排序操作
for(i = 1;i<length;i++){
left=0,right=i-1;
// mid=(right+left)/2; mid在此处赋值,那么后续的mid的值不会改变,应该放在while循环中,动态修改mid值
temp=list[i];
while(left<=right){
mid=(right+left)/2; //在while循环中动态修改mid值
if (temp>=list[mid])
{
left=mid+1;
}
else
{
right=mid-1;
}
}
//while循环结束时此时left>right
//此时left所指的位置就是temp要插入的位置
//直接让有序序列right之后的元素后移(此时left>right)
for(j=i-1;j>right;j--){
list[j+1]=list[j];
}
//最后把temp元素插入left指针指向的位置
list[j+1]=temp;
}
}