当前位置:   article > 正文

归并排序和快速排序_对n个记录进行归并排序,平均复杂度,最坏时时间复杂度

对n个记录进行归并排序,平均复杂度,最坏时时间复杂度

一、归并排序

排序算法稳定性:假定在待排序的记录序列中,存在多个具有相同的关键字的记录,若经过排序,这些记录的相对次序保持不变,即在原序列中,r[i]=r[j],且r[i]在r[j]之前,而在排序后的序列中,r[i]仍在r[j]之前,则称这种排序算法是稳定的;否则称为不稳定的。

1、归并排序是稳定的排序算法

归并排序稳不稳定关键在于merge函数。在合并过程中,如果A[p..q]和A[q+1...r]之间有值相同元素,先把A[p...q]中的元素放入tmp数组。这样就保证了值相同的元素,在合并的先后顺序不变

归并处理过程由下到上,先处理子问题,在合并

2.时间复杂度 O(nlogn)

递归代码的时间复杂度可以写成递推公式。

(1)假设对n个元素规定需要的时间是T(n),分解成两个子数组排序的时间T(n/2)

(2)merge函数时间复杂度O(n)

归并排序的时间复杂度计算公式:

T(1) = C; n = 1,只需要常量级的执行时间C

T(n)=2*T(n/2) + n; n > 1

进一步分解得出结论,得出结论T(n)=2^kT(n/2^k) +kn,当T(n/2^k)=T(1)时,就是n/2^k得到k=log2(n),带入公式得到,T(n)=Cn+nlog2n

时间复杂度稳定,最好最坏,平均都是O(nlogn)

3.空间复杂度O(n)

在任意时刻,CPU只会有一个函数在执行,只会有一个临时的内存在使用。临时内存空间最大不会超过n个数据大小

4.缺点

(1)不是原地排序算法,merge函数需要借助额外存储空间

先局部有序,然后在整体有序

二、快速排序

1.快速排序是原地、不稳定的排序算法

代码:快速排序代码实现_INGNIGHT的博客-CSDN博客

比如数组:6,5,6,3,4,经过第一次分区之后,两个6的顺序会有改变。(选取下表最高的值4为pivot)

快排处理过程由上到下,先分区,在处理子问题。原地排序,解决归并排序占用过多内存问题。

2.时间复杂度 O(nlogn)

3.空间复杂度O(1)

4.缺点

(1)每次分区操作,选择的pivot都很合适,正好能将大区间对等一分为二。原数据已经有序,1,3,5,6,8,每次选取最后一个元素作为pivot,每次分区得到的两个区间都是不均等的,需要进行大约n次分区操作。每次分区平均扫面大约n/2个元素,这是快排时间复杂度退化为O(n^2)

 先整体有序,在局部有序

题目:

https://blog.csdn.net/INGNIGHT/article/details/131625238

215. 数组中的第K个最大元素-CSDN博客

12 | 排序(下):如何用快排思想在O(n)内查找第K大元素?归并排序和快速排序-CSDN博客

algo/c-cpp/12_sorts/quick_sort.c at master · wangzheng0822/algo · GitHub

  1. class Solution {
  2. public:
  3. vector<int> sortArray(vector<int>& nums) {
  4. if (nums.size() <= 0) {
  5. return nums;
  6. }
  7. quick_sort(nums, 0, nums.size()-1);
  8. return nums;
  9. }
  10. private:
  11. void quick_sort(std::vector<int>& nums, int left, int right) {
  12. if (left >= right) {
  13. return;
  14. }
  15. int mid = partition(nums, left, right);
  16. // mid然后的右边区间起始点
  17. quick_sort(nums, left, mid-1);
  18. quick_sort(nums, mid, right);
  19. }
  20. int partition(std::vector<int>& nums, int left, int right) {
  21. int index = random() %(right-left+1);
  22. swap(nums[left], nums[left+index]);
  23. int val = nums[left];
  24. // 和val相等的元素均匀的分布在左右两边
  25. while (left <= right) {
  26. while (left <= right && nums[left] < val ) {
  27. ++left;
  28. }
  29. while (left <= right && nums[right] > val) {
  30. --right;
  31. }
  32. // 两个和val相等的元素也会进行交换
  33. if (left <= right) {
  34. swap(nums[left], nums[right]);
  35. ++left;
  36. --right;
  37. }
  38. }
  39. // 此时left一定是在right的右边
  40. return left;
  41. }
  42. };
  1. class Solution {
  2. public:
  3. vector<int> sortArray(vector<int>& nums) {
  4. if (nums.size() <= 0) {
  5. return nums;
  6. }
  7. quick_sort(nums, 0, nums.size()-1);
  8. return nums;
  9. }
  10. private:
  11. void quick_sort(std::vector<int>& nums, int left, int right) {
  12. if (left >= right) {
  13. return;
  14. }
  15. std::pair<int, int> mid = partition(nums, left, right);
  16. // mid然后的右边区间起始点
  17. quick_sort(nums, left, mid.second);
  18. quick_sort(nums, mid.first, right);
  19. }
  20. std::pair<int, int> partition(std::vector<int>& nums, int left, int right) {
  21. int index = random() %(right-left+1);
  22. swap(nums[left], nums[left+index]);
  23. int val = nums[left];
  24. // 和val相等的元素均匀的分布在左右两边
  25. while (left <= right) {
  26. while (left <= right && nums[left] < val ) {
  27. ++left;
  28. }
  29. while (left <= right && nums[right] > val) {
  30. --right;
  31. }
  32. // 两个和val相等的元素也会进行交换
  33. if (left <= right) {
  34. swap(nums[left], nums[right]);
  35. ++left;
  36. --right;
  37. }
  38. }
  39. // 此时left一定是在right的右边
  40. return std::pair<int, int>(left, right);
  41. }
  42. };

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/小蓝xlanll/article/detail/430071
推荐阅读
相关标签
  

闽ICP备14008679号