排序
-
- 时间复杂度
- 由上图可知,4 个石子的时候排完序需要 3 趟,第一趟需要比较3次,第二趟需要比较2次,第三趟需要比较1次,那一共比较了 3 + 2 + 1 次;
- 那如果有 n 个石子呢?那就需要 (n-1) + (n-2) +…+2+1 次,这不就是一个等差数列
- 时间复杂度
-
-
- 根据复杂度的规则,去掉低阶项(也就是 n/2),并去掉常数系数,那复杂度就是 **O(n^2)**了;
- 冒泡排序也是一种稳定排序,因为在两个数交换的时候,如果两个数相同,那么它们并不会因为算法中哪条语句相互交换位置。
-
- 2.选择排序
- 选择排序(图解)_RainySouL1994的博客-CSDN博客_选择排序
- 1.简单选择排序工作原理
- 是每一次从待排序的数据元素中选出最小(最大)的一个元素,存放在序列的起始位置,然后,再从剩余未排序元素中继续寻找最小(大)元素,然后放到已排序序列的末尾。以此类推,直到全部待排序的数据元素排完。
- 选择排序是不稳定的排序方法。
- 稳定排序指,按对象中不同字段进行多次排序,不会打乱同值元素的顺序
- 不稳定排序则反之
-
- 时间复杂度:O(n^2),相比较冒泡排序,每次比较后,只更新最小值的下标,每轮循环值最多只做一次值交换。时间上得到了很大的提升。但是也是使用了双层循环,时间复杂度和冒泡排序的一样。
- 2.堆排序
- 大根堆&小根堆
- 3.插入排序
- 直接插入排序
- 原理:
- 直接插入排序是稳定的
- 在上面已经提到了这个插入排序是按照相对位置进行插入的,因此每次插入的时候如果判断到有相同的数,将当前的数放在相同数的后一个位置就保证了其稳定性。
- 因为前面那个数在原本的序列中是在当前数的前面,因此先被插入进来,如果要保证他们的稳定性就要保证前面的数依旧排在前面。
- 因此当判断条件为:while(j >= 0 && arr[j] > u) 时是稳定的,
- 但是如果判断条件为while(j >= 0 && arr[j] ≥ u)时是不稳定的。
- 因为插入排序可以达到稳定,因此称插入排序是稳定的。
- 与已知序列的数进行比较,可以从小到大也可以从大到小,如果是从小到大的话就是找到第一个比他大的数前面插入 如果是从大到小就是找到第一个比他小的数后面插入,后面的数向后移动一位。
- 直接插入排序是稳定的
- 原理:
- 直接插入排序
-
-
- 代码
-
-
-
- 时间复杂度
- 第二种解法也是 O(n2)的时间复杂度,但是不是满 n2 次的,因为其是从后往前找,因此判断和移动一起做,因此遍历的次数不会满 n2,除非是特殊序列,就是倒序序列进行排序才会跟上面的时间复杂度一样。
- 因此第二种解法的最坏时间复杂度为 O(n2),最好的时间复杂度是发生在原本就有序的情况,其时间复杂度是 O(n)的
- 因此总结一下使用插入排序的时间复杂度最坏情况是 O(n2)最好是 O(n)
- 时间复杂度
- 二分插入排序
- 稳定
- 二分插入排序(c语言)_我滴天呐我去的博客-CSDN博客_二分插入排序
- 原理:
- 二分法插入排序,简称二分排序,是在插入第i个元素时,对前面的0~i-1元素进行折半,先跟他们中间的那个元素比,如果小,则对前半再进行折半,否则对后半进行折半,直到left
- 代码
- 时间复杂度:最坏情况是 O(n2)最好是 O(n),最好的情况是当插入的位置刚好是二分位置。
- 希尔排序
- 不稳定
- 原理:希尔排序_天地高歌的博客-CSDN博客_希尔排序
- 代码
- 时间复杂度:平均情况是0(NlogN),最坏情况是:o(N2)
-
- 4.归并排序
- 5.快速排序
-
- 时间复杂度:最好O(nlogn),在最坏的情况下,这个数仅有右子树或左子树,比较次数为 (n-1)+(n-2) + (n-3) + … +1=n*(n-1)/2 ,因此时间复杂度为O(n^2)
- 6.基数排序
- 快速排序相对于其他排序效率更高的原因:
- 为什么快速排序算法效率比较高? - 云+社区 - 腾讯云
- 大大减少了比较和交换的次数,因为按基准数切分的两半数组,在一个数组里面的数据是绝对不会和第二个数组里面的数字产生比较的机会的,所以大幅度降低了做无用功的机会。
- 系统自带排序实现