本文共 3226 字,大约阅读时间需要 10 分钟。
时间复杂度: 插入,冒泡,选择排序:O ( n^2 ) 快排,归并排序:O ( nlogn ) 桶,计数,基数排序:O ( n )
举例,订单按金额排序,但要求相同金额的订单,按照创建时间排序 所以,可以先按照创建时间排序,然后选择稳定的排序算法,按照金额排序,这样就可以满足要求
冒泡排序,是原地排序算法,空间复杂度 O ( 1 ),每次循环,两两元素进行比较,将最大的元素不断下沉,直到成为数组末尾元素;
冒泡是稳定排序算法,相等的元素,并不会交换次序,并且设计算法时,在一次遍历中,没有元素交换,就可以认为数据已经有序,无需下次遍历;
最坏时间复杂度:初始状态的有序度是 0,要进行 n*(n-1)/2 次交换 最好时间复杂度:初始状态的有序度是 n*(n-1)/2,一次遍历,没有元素交换,就结束排序 平均时间复杂度:使用概率论计算比较复杂,但可以通过有序度来粗略计算 取中间值 n*(n-1)/4 次交换 所以简单统计,平均时间复杂度是 O ( n^2 )
空间复杂度是 O(1) 最好时间复杂度是 O(n):当每次都是在排序区间最后插入元素,插入时间复杂度是 o(1) 最坏时间和平均时间复杂度是 O(n^2):每次插入时间复杂度是 o(n) 平均时间复杂度:是每次向有序集合,插入一个元素的平均时间复杂度是 O(n),所以平均时间复杂度,是 O(n^2)
空间复杂度 O(1) 最好,最坏,平均时间复杂度,都是 O(n^2),每次选择时间复杂度都是 O(n),共进行 n 次选择 不稳定的排序算法,因为每次都需要交换元素,就可能破坏了未排序区间元素的顺序性
相比于冒泡排序,交换元素操作更简单,冒泡排序需要三行代码执行交换,插入只需一行 相比于选择排序,插入是稳定性排序,而选择排序不是
都使用分治思想,将大问题划分为小问题来解决,都用递归来实现;
归并排序,是将集合等分为两个子集合,分别进行排序后,合并两个有序子集合,然后子集合,同样进行等分,排序,合并,如此递归,直到集合剩余一个元素;
递推公式是 f(p...q) = merge(f(p...r),f(r...q)),merge,合并两个有序的数组 终止条件是 p == r 或者 q == r 是稳定排序算法,要求合并有序集合中,相同的元素,将前面集合先放入
归并时间复杂度 T(n) = 2*T(n/2) + n,其中最后一个 n 是合并两个有序集合 n/2 的时间复杂度 截至条件 T(1) = C,C 是常量 T(n) = 2*(2*T(n/4) + n/2) + n = 4*T(n/4) + 2*n = 2^(k)*T(n/2^(k)) + kn,因为k次等分后 2^k = n 最终得到 T(n) = nlog2n + Cn 所以归并排序的时间复杂度是 O(nlogn),并且没有最好和最坏的区分,都需要递归这么多次
// 排序A数组,从p到r的元素,等于根据基准数交换数据后,分为小于基准数的p到q的元素,和大于基准数的q到r的元素 // 然后分别进行递归快速排序 递推公式:fastSort(A,p,r) = fastSort(A,p,q-1) + fastSort(A,q+1,r) 终止条件是:p == r quick_sort_c(A, p, r) { if p >= r then return // 对p到r元素进行分区,得到分区点 q = partition(A, p, r); quick_sort_c(A, p, q-1); quick_sort_c(A, q+1, r); }
注意,这里基准数的选择,觉得了快排效率,简单选择最左边,或者最右边,更优化是三点选取,随机选择等 基准数如果选最左边,要先从右往左进行查找,因为这样,最终左右指针相遇的点,是从左往右得到的,比基准数大, 且交换后的元素,即比基准数小,那么最后一次交换,就是正确的,反之会最后是从右往左,比基准数小,且交换后 的元素,即比基准数大,这样,是无法与最左边的基准数交换,交换后就是错误的
快速排序,每次分区时间复杂度是 O(n) 最好时间复杂度:每次都是等分,进行 log2n 次分区,所以最好时间复杂度是 O (nlogn) 最差时间复杂度:进行了 n 次分区,每次分区都是一个元素 + 剩余元素,所以最坏时间复杂度是 O(n^2) 平均时间复杂度是 O (nlogn);
第 k 大的元素,即集合中只有 k-1 个元素,比其大 按照快排的思路,选择基准值,进行分区后,分区点是 p,要求比 A[p] 大,放集合左部分, 所以集合中,有 p 个元素,比 A[p] 大,如果 p =k-1,那么就要 k-1 个元素比 A[p] da, A[p] 即为所求 如果 p > k-1,那么在左边集合查找 如果 p < k-1,那么在右边集合查找 如此递归,最终递归终止条件,p + 1 = k 时间复杂度:第一次分区,需扫描全部数据,第二次分区,n/2 数据,如此递归计算 n + n/2 + n/4 + ... + 1, n(1/2)^k = 1,得到 2^k = n,等比数列求和 a(1-q^n)/1-q = n(1-(1/2)^k)/(1-1/2) = 2n(1-1/n) = 2n -2 所以时间复杂度是 O(n)
典型的归并排序,只不过排序 1GB 数据后,需要写入磁盘
转载地址:http://osfin.baihongyu.com/