文章目录
前言
手撕排序算法第一篇:插入排序!
从本篇文章开始,我会介绍并分析常见的几种排序,例如像插入排序,冒泡排序,希尔排序,选择排序,快速排序,堆排序,归并排序等等!
这篇文章我先来给大家手撕一下插入排序!
大家可以点下面的链接去阅读其他的排序算法:
C语言手撕排序算法
正文开始!
一、常见的排序算法
二、插入排序的实现
2.1 基本思想
直接插入排序是一种简单的插入排序法,其基本思想是:
把待排序的记录按其关键码值的大小逐个插入到一个已经排好序的有序序列中,直到所有的记录插入完成为止,得到一个新的有序序列。
实际中我们玩扑克牌时,就用了插入排序的思想
2.2 直接插入排序
当插入第i(i>=1)个元素时,前面的array[0],array[1],…,array[i-1]已经排好了序,此时用array[i]的排序码与array[i-1],array[i-2],…的排序码顺序进行比较,找到插入为止即将array[i]插入,原来位置上的元素顺序向后移动。
2.2.1 单趟排序的代码实现
//单趟[0,end]有序,end+1位置的值插入进去,保持它依旧有序。
//[0,end] end +1
int end;
int tmp = a[end + 1];
while (end >= 0)
{
if (a[end] > tmp)
{
a[end + 1] = a[end];
end--;
}
else
{
break;
}
}
a[end + 1] = tmp;
三、插入排序代码实现
在单趟排序的基础之上,我们写一个大循环即可解决整个数组。
void InsertSort(int* a,int n)
{
for (int i=0;i<n-1;i++)
{
//[0,end] end +1
int end=i;
int tmp = a[end + 1];
while (end >= 0)
{
if (a[end] > tmp)
{
a[end + 1] = a[end];
end--;
}
else
{
break;
}
}
a[end + 1] = tmp;
}
}
四、插入排序测试
void PrintArray(int* a, int n)
{
for (int i = 0; i < n; i++)
{
printf("%d ",a[i]);
}
printf("\n");
}
void InsertSort(int* a,int n)
{
for (int i=0;i<n-1;i++)
{
//[0,end] end +1
int end=i;
int tmp = a[end + 1];
while (end >= 0)
{
if (a[end] > tmp)
{
a[end + 1] = a[end];
end--;
}
else
{
break;
}
}
a[end + 1] = tmp;
}
}
void TestInsertSort()
{
int a[] = {6,3,1,4,2,5};
printf("排序前:");
PrintArray(a, sizeof(a) / sizeof(a[0]));
InsertSort(a,sizeof(a)/sizeof(a[0]));
printf("排序后:");
PrintArray(a, sizeof(a) / sizeof(a[0]));
}
int main()
{
TestInsertSort();
return 0;
}
五、插入排序的时间复杂度
5.1 最坏的情况下
最坏的情况就是逆序排顺序然后进行头插,每次交换的次数为1+2+3+…+n;
所以时间复杂度是O(n^2)。
5.2 最好的情况下
最好的情况就是本来有序的数组进行排序,每次插入都是在尾部,比较的次数为n;
所以时间复杂度是O(n)。
六、直接插入排序特性总结
直接插入排序的特性总结:
1.元素越接近有序,直接插入排序算法是一种效率比较高的排序算法
2.时间复杂度为:O(n^2)
3.空间复杂度为:O(1),它是一种稳定的排序算法。
总结
(本篇完!)
下一篇我来给大家讲解关于希尔排序,希尔排序是基于插入排序的一种延展。