前言:排序是程序员在面试时经常遇到的面试题,排序方法种类繁多,常见的有插入、希尔、选择、堆排、冒泡、快排、归并排序 这7种排序方式
各种排序的时间复杂度:
一、插入排序:
插入排序是一种简单排序,它的思路是:每次从未排好的序列中选出第一个元素插入到已排好的序列中。它的算法步骤可以大致归纳如下:
1. 从未排好的序列中拿出首元素,并把它赋值给temp变量;
2. 从排好的序列中,依次与temp进行比较,如果元素比temp大,则将元素后移(实际上放置temp的元素位置已经空出)
3. 直到找到一个元素比temp小, 将temp放入该位置;
动图演示:
代码:
void Insertion_Sort(int *arr, int sz)
{
int i = 0;
int j = 0;
for (i = 1; i < sz; i++)
{
int tmp = arr[i];
for (j = i; (j > 0) && (arr[j - 1] > tmp); j--)
{
arr[j] = arr[j-1];
}
arr[j] = tmp;
}
printf("Insertion_Sort:");
Print(arr, sz);
}
二、希尔排序:
希尔排序的实质就是分组插入排序,该方法又称缩小增量排序,因DL.Shell于1959年提出而得名。 该方法的基本思想是:
先将整个待排元素序列分割成若干个子序列(由相隔某个“增量”的元素组成的)分别进行直接插入排序,然后依次缩减增量再进行排序,待整个序列中的元素基本有序(增量足够小)时,再对全体元素进行一次直接插入排序。因为直接插入排序在元素基本有序的情况下(接近最好情况),效率是很高的,因此希尔排序在时间效率上比前两种方法有较大提高 。
如何选择有效的希尔增量:
每一轮的希尔增量之间如果是等比的,就会导致希尔增量盲区。为了保证分组粗度没有盲区,每一轮的增量需要彼此互质。其中比较有代表性的是Hibbard增量( 2^k-1)和Sedgewick增量( 4^k - 3*2^k + 1)。
动图演示:
代码:
void Shell_Sort(int *arr, int sz)
{
int gap = sz;//gap越小越接近有序
while (gap > 1)
{
gap = gap / 3 + 1;
for (int i = 0; i < sz - gap; i++)//每组同时进行
{
int end = i;
int tmp = arr[end + gap];
while (end >= 0 && arr[end] > tmp)
{
arr[end + gap] = arr[end];
end -= gap;
}
arr[end + gap] = tmp;
}
}
printf("Shell_Sort:");
Print(arr, sz);
}
三、选择排序
选择排序是一种简单直观的排序方法,遍历一遍数组,找到最小的那个元素,与数组第一个元素交换,然后,再从剩余未排序元素中继续寻找最小(大)元素,放到已排序序列的末尾。以此类推,直到所有元素均排序完毕。
而且这个方法还可以优化,定义一个左指针,定义一个右指针;左指针从前往后遍历,找到最小的元素放到