简单排序传送门
👉 简单排序
归并排序
传送门👉 归并排序
堆排序
传送门👉 堆排序
希尔排序
希尔排序可以说是直接插入排序的进阶版
基本思想
先取一个小于n的整数d1作为第一个增量,把文件的全部记录分组。所有距离为d1的倍数的记录放在同一个组中。先在各组内进行直接插入排序;然后,取第二个增量d2<d1重复上述的分组和排序,直至所取的增量 =1( < …<d2<d1),即所有记录放在同一组中进行直接插入排序为止。
该方法实质上是一种分组插入方法
比较相隔较远距离(称为增量)的数,使得数移动时能跨过多个元素,则进行一次比较就可能消除多个元素交换。D.L.shell于1959年在以他名字命名的排序算法中实现了这一思想。算法先将要排序的一组数按某个增量d分成若干组,每组中记录的下标相差d.对每组中全部元素进行排序,然后再用一个较小的增量对它进行,在每组中再进行排序。当增量减到1时,整个要排序的数被分成一组,排序完成。
一般的初次取序列的 一半为增量,以后每次减半,直到增量为1。
一个具体例子:
第一趟:
第二趟:
第三趟:
此躺不会影响上一趟已排好序列
代码:
void shell_sort(int a[], int n)
{
int d, j, k;
int t;
for(d = n / 2; d > 0; d /= 2) // 其实就是将 0 的地方全部改成 d
{
for(j = d; j < n; j++)
{
t = a[j];
for(k = j - 1; k >= d && a[k - d] > t; k--)
a[k] = a[k - d];
a[k] = t;
}
}
}
① 时间复杂度:O(n^(1.3—2))
② 希尔排序为不稳定排序
快速排序
基本思想
通过一趟排序将要排序的数据分割成独立的两部分,其中一部分的所有数据都比另外一部分的所有数据都要小,然后再按此方法对这两部分数据分别进行快速排序,整个排序过程可以递归进行,以此达到整个数据变成有序序列。
① 选择一个基准点,一般选择区间最左端元素(上图选择的是区间最右端)
② 设置 右、左 指针,分别从 右端、左端 开始 。 假如 右指针 指向的元素 大于等于 基准 点,则 右指针 向左移动,否则停止 。 接下来 假如 左指针 指向的元素 小于等于 基准点,则 左指针 向右移动,否则停止 。(为了确保 左边部分总是小于等于基准点,右部分总是大于等于基准点)
③ 右指针、左指针 指向的元素相互交换,继续执行 第②步。 直到右指针 与 左指针 重合
④ 将此时 两个指针所共同指向的元素 与 基准点 相互交换
⑤ 接下来是递归操作:以 两个指针共同指向的位置 作为 分界线; 前后两个部分 都进行与前四步相同的操作
代码:
void quick_sort(int a[], int l, int r)
{
if(l >= r) // 递归结束条件
return;
int t = a[l];
int i = l, j = r;
while(i < j)
{
while(i < j && a[j] >= t) // 右指针的移动
j--;
while(i < j && a[i] <= t) // 左指针的移动
i++
if(i < j)
{
int h = a[i];
a[i] = a[j];
a[j] = h;
}
}
a[l] = a[i];
a[i] = t;
// 对分成的两部分继续进行排序
quick_sort(a, l, i);
quick_sort(a, i + 1, r);
}
快速排序并不是所有情况都快:
① 最坏情况:序列接近有序,时间复杂度为 O(n * n)
② 最好情况:序列接近无序,时间复杂度为O(n logn)
③ 快速排序为不稳定排序
表排序
我们平常用的排序都是直接用于值交换(数字、字符等),但是在实际生活我们可不是仅仅只交换数字或者字符,一般都是一大部分内容的移动;直接进行值交换的话,时间的花费是相当恐怖的。
表排序:将 “指针” 进行排序(“指针” 并不是 C里的指针)。
我们继续用之前 直接插入排序的扑克牌举例:
代码:
void table_sort(int card[], int table, int n) // card 下标从0开始 0
{
int i, j;
int t;
for(i = 0; i < n; i++)
table[i] = i;
for(i = 1; i < n; i++)
{
t = table[i];
for(j = i; j > 0 && card[table[j - 1]] > card[t]; j--)
table[j] = table[j - 1];
table[j] = t;
}
}
此处只是拿直接插入排序做例子
① 用到其他排序里也是同样的,但是要记得是换下标,时间复杂度与这些排序复杂度匹配
② 写的时候要细心,很容易出错