在学习数据结构中我感觉最重要的就是排序算法,以下我列举最常见的几种排序算法及他们各自的思想
接下来我一一介绍这几种排序算法:
1.直接插入排序
直接插入排序是一种简单的插入排序法,其基本思想是:把待排序的记录按其关键码值的大小逐个插入到一
个已经排好序的有序序列中,直到所有的记录插入完为止,得到一个新的有序序列 。
代码实现:
void InsertSort(int *array, int size)
{
//直接从第二个元素开始,因为第一个元素已经有序
for (int i = 1; i < size; i++)
{
int key = array[i];//key为待排元素
int end = i - 1;//end为比较元素
while (end >= 0 && key < array[end])
{
array[end + 1] = array[end];//把end位置的元素放到end+1的位置
end--;
}
array[end + 1] = key;
}
}
性质:
- 适用场景:元素接近有序,直接插入排序算法的时间效率越高
- 空间复杂度:o(n^2)
- 时间复杂度:o(1)
- 稳定性:稳定
2.希尔排序
希尔排序(Shell Sort)是插入排序的一种。是针对直接插入排序算法的改进。该方法又称缩小增量排序,因D.L.Shell于1959年提出而得名。希尔排序法的基本思想是:选定一个整数,把待排序文件中所有元素按整数的间隔分组,并对每一组内的记录进行排序。然后,取,重复上述分组和排序的工作。每次整数减一,当整数到达1时,这时所有记录在统一组内排好序。
代码实现:
void ShellSort(int *array, int size)
{
//gap作为分组的依据
int gap = size;
while (gap > 1)
{
gap = gap / 3 + 1;//
for (int i = gap; i < size; i++)
{
int key = array[i];
int end = i - gap;
while (end >= 0 && key < array[end])
{
array[end + gap] = array[end];
end -= gap;
}
array[end + gap] = key;
}
}
}
性质:
- 希尔排序是对直接插入排序的优化。
- 当gap > 1时都是预排序,目的是让数组更接近于有序。当gap == 1时,数组已经接近有序的了,这样就
会很快。这样整体而言,可以达到优化的效果。我们实现后可以进行性能测试的对比。 - 平均时间复杂度: O(N1.3—N2)
- 空间复杂度:o(n)
- 稳定性:不稳定
3.选择排序
选择排序的基本思想是:每一次从待排序的数据元素中选出最小(或最大)的一个元素,存放在序列的起始位置,用剩余的数据和其相比较,每次找到数据中最大或者最小的元素,循环进行直到全部待排序的数据元素排完 。
代码实现:
void SelectSort(int *array, int size)
{
for (int i = 0; i < size-1; i++)//控制循环的趟数
{
int maxpos = 0;
for (int j = 1; j < size - i; j++)
{
if (array[j] > array[maxpos])//比较j和maxpos位置元素的大小,看maxpos位置是否合适
{
maxpos = j;
}
}
if (maxpos != size - 1 - i)//第一次比较结束时,判断maxpos是不是在末尾
{
swap(&array[maxpos], &array[size - 1 - i]);
}
}
}
性质:
- 时间复杂度:O(N^2)
- 空间复杂度:O(1)
- 稳定性:不稳定
上边的选择排序:一次只可以找出一个最大或者最小的元素,效率比较低,所以对选择排序进行优化,代码如下:
//选择排序的优化
void SelectSortMax(int *array, int size)
{
int begin = 0;
int end = size -