• 插入排序和归并排序


    插入排序,Insertion Sort.

    给出伪代码

    1. for i = 1,2,...,n-1
    2. Insert A[i] into Sorted array A[0:i-1]
    3. by swaping down to the correct position.

    冒泡排序

    冒泡排序就是一种插入排序算法。

    1. i1
    2. while i < length(A)
    3. j ← i
    4. while j > 0 and A[j-1] > A[j]
    5. swap A[j] and A[j-1]
    6. j ← j - 1
    7. end while
    8. ii + 1
    9. end while

    冒泡排序的时间复杂度为O(n^2)

    二分插入排序

    对于如何找到正确的位置the correct position,由于A[0:i-1]是已经排序的数组,因此可以对A[0:i-1]进行二分搜索,找到刚好小于A[i]的元素A[j],暂存给一个变量num,再将A[j+1:i-1]整体后移一位,最后将num赋值给A[j]。

    但是使用二分插入排序的平均时间复杂度依然是O(n^2),因为每次找到正确的位置,可能需要移动许多的元素。其实效率并不比冒泡快多少。

    插入排序的空间复杂度为O(1),是一种就地(in-place)的算法。

    并归排序

    Merge Sort

    算法思路:将一个未排序的大小为n的数组A,分为两个大小相似(n/2)的数组L和R;分别对这两个数组进行排序,排序后的数组分别为L'和R';再将L'和R'合并为已排序的数组A'。

    我们可以通过画递归树或者使用主定理计算改算法的渐进时间复杂度。

    C++实现归并排序的代码

    1. class Solution {
    2. public:
    3. vector<int> sortedA;
    4. vector<int> sortArray(vector<int>& nums) {
    5. sortedA.resize(nums.size());
    6. mergeSort(nums, 0, nums.size()-1);
    7. return nums;
    8. }
    9. void mergeSort(vector<int>& nums, int left, int right)
    10. {//merge sort
    11. //take the array A apart into array L = A[0:n/2] and array R = A[n/2+1:n-1]
    12. //sort the array L and R
    13. //merge them together into the sorted array A'
    14. if(left >= right)
    15. {
    16. return;
    17. }
    18. int mid = ((right-left) >> 1) + left;
    19. mergeSort(nums, left, mid);
    20. mergeSort(nums, mid+1, right);
    21. mergeTwoSortedArray(nums, sortedA, left, mid, right);
    22. }
    23. void mergeTwoSortedArray(vector<int>& nums, vector<int>& sortedA, int left, int mid, int right)
    24. {//合并两个已排序的数组
    25. //int size = nums.size();
    26. //array L = nums[left:mid]
    27. //array R = nums[mid+1:right]
    28. int i = left;
    29. int j = mid+1;
    30. int count = 0;
    31. while(i <= mid && j <= right)
    32. {
    33. if(nums[i] < nums[j])
    34. {
    35. sortedA[count] = nums[i];
    36. ++count;
    37. ++i;
    38. }
    39. else if(nums[i] == nums[j])
    40. {
    41. sortedA[count] = nums[i];
    42. ++count;
    43. sortedA[count] = nums[j];
    44. ++count;
    45. ++i;
    46. ++j;
    47. }
    48. else
    49. {
    50. sortedA[count] = nums[j];
    51. ++count;
    52. ++j;
    53. }
    54. }
    55. while(j <= right)
    56. {
    57. sortedA[count] = nums[j];
    58. count++;
    59. ++j;
    60. }
    61. while(i <= mid)
    62. {
    63. sortedA[count] = nums[i];
    64. ++count;
    65. ++i;
    66. }
    67. for(int i = 0;i < right - left + 1;++i)
    68. {
    69. nums[i+left] = sortedA[i];
    70. }
    71. }
    72. };

  • 相关阅读:
    在 .NET 中使用 FixedTimeEquals 应对计时攻击
    jupternotebook和jupterLab有什么区别?
    Word Power S
    【SSM】SpringMVC系列——SpringMVC注解式开发1
    【知识增强】A Survey of Knowledge-Enhanced Pre-trained LM 论文笔记
    编程实例:多人同时计时计费管理系统软件,可适用于钓场计时等管理
    wpf devexpress实现输入验证使用验证规则
    UGUI不规则响应区域(例如多个按钮重叠,避免点击错误)
    【C++】实现unqiue_ptr
    2022世界杯漫谈与猜想,谁是你心目中的第一
  • 原文地址:https://blog.csdn.net/qq_64137391/article/details/136518388