排序算法
前言
排序在我们生活中处处可见,例如在考完试后通过成绩划分排名的高低,军训时按身高的高矮战队,打扑克牌时摆牌的顺序等,这些场景都会用到排序。而在我们的计算机中也会使用排序算法堆数据进行比较,接下来就和小编一起用C语言来实现一些计算机中常见的排序把。
1.排序的分类
常见的排序分为四类:插入排序、选择排序、交换排序、归并排序。
(1)插入排序:直接插入排序、希尔排序。
(2)选择排序:直接选择排序、堆排序。
(3)交换排序:冒泡排序、快速排序。
(4)归并排序:归并排序。
2.直接插入排序
<1>直接插入排序算法思想
直接插入排序的算法思想是把待排序数组中的最前面的值插入到有序数组,直到没有待排的数据,我们平时打扑克牌不停地拿牌给扑克牌排序就是利用了类似的思想。
<2>直接插入排序动图演示
<3>直接插入排序的代码演示
//直接插入排序
void InitSort(int* arr, int n)
{
for (int i = 0; i < n - 1; i++)
{
int end = i;
int tmp = arr[end + 1];
//将待排序的元素插入到有序元素中
while (end >= 0)
{
if (arr[end] > tmp)
{
arr[end + 1] = arr[end];
end--;
}
else
{
break;
}
}
arr[end + 1] = tmp;
}
}
<4>直接插入排序时间复杂度与空间复杂度以及稳定性
(1)时间复杂度:o(n^2)。
(2)空间复杂度:o(1)。
(3)稳定性: 稳定。
<5>直接插入排序的注意事项
逆序的时候时间复杂度最差,一般不会用这种情况。
3.希尔排序
<1>希尔排序的算法思想
希尔排序的算法思想是把 一套数据换分成若干组数据,然后对每一组数据进行直接插入排序,然后再划分成若干组进行直接插入排序,直到最后所有数据化分为一组然后在进行直接插入排序(每次分的组都要比前一次每组元素个数要少)。
<2>希尔排序动图演示
<3>希尔排序的代码演示
//希尔排序
void ShellSort(int* arr, int n)
{
int gap = n;
while (gap > 1)
{
//把数据分为gap组,+1是因为要保证最后一次的gap值必须为1。
gap = gap / 3 + 1;
//开始对每组数据进行直接插入排序,需要注意end加或减的值
for (int i = 0; i < n - gap; i++)
{
int end = i;
int tmp = arr[end + gap];
while (end >= 0)
{
if (arr[end] > tmp)
{
arr[end + gap] = arr[end];
end -= gap;
}
else
{
break;
}
}
arr[end + gap] = tmp;
}
}
}
<4>希尔排序的时间复杂度与空间复杂度以及稳定性
(1)时间复杂度:o(n^1.3)。
(2)空间复杂度:o(1)。
(3)稳定性:不稳定。
<5>希尔排序的注意事项
(1)直接插入排序相当于选择排序的优化,把数据划分为多组组进行直接插入排序大大减少了数据需要移动的步数。
(2)组数也不是分的越多越好这里小编推荐每次除以三,不要问为什么。
(3)希尔排序的时间复杂度现在仍然是数学界的一大难题,不必去深究,记住就行。