归并排序——有序序列的合并

目录

1、简述

2、复杂度

3、稳定性

4、例子


1、简述

有序序列的合并(Merge of Sorted Sequences)是归并排序的核心步骤之一。其目的是将两个已经排序的序列合并成一个新的有序序列。这个过程在归并排序中非常重要,因为归并排序通过递归地将序列分割成子序列,然后合并这些子序列来实现排序。

实现步骤

  1. 创建临时数组

    • 用于存储两个子序列的数据,以便合并操作。
  2. 双指针法

    • 使用两个指针分别指向两个子序列的开头。
    • 比较指针所指向的元素,将较小的元素放入临时数组中,然后移动指针。
  3. 处理剩余元素

    • 当一个子序列的元素全部被处理完后,将另一个子序列的剩余元素直接复制到临时数组中。
  4. 将临时数组的内容复制回原数组

    • 合并完成后,将临时数组中的数据复制回原数组对应的位置。

2、复杂度

  • 时间复杂度

    • O(n),其中 n 是两个有序序列的总长度,因为每个元素都只处理一次。
  • 空间复杂度

    • O(n),需要额外的空间来存储临时数组。

3、稳定性

有序序列的合并是稳定的,因为在合并过程中,相同元素的相对位置不会改变。

4、例子

#include <iostream>
#include <vector>

// 合并两个有序子数组
void merge(std::vector<int>& arr, int left, int mid, int right) {
    int n1 = mid - left + 1;
    int n2 = right - mid;

    // 创建临时数组
    std::vector<int> L(n1);
    std::vector<int> R(n2);

    // 复制数据到临时数组 L[] 和 R[]
    for (int i = 0; i < n1; ++i)
        L[i] = arr[left + i];
    for (int i = 0; i < n2; ++i)
        R[i] = arr[mid + 1 + i];

    // 合并临时数组到原数组
    int i = 0, j = 0, k = left;
    while (i < n1 && j < n2) {
        if (L[i] <= R[j]) {
            arr[k] = L[i];
            ++i;
        } else {
            arr[k] = R[j];
            ++j;
        }
        ++k;
    }

    // 复制剩余元素(如果有)
    while (i < n1) {
        arr[k] = L[i];
        ++i;
        ++k;
    }

    while (j < n2) {
        arr[k] = R[j];
        ++j;
        ++k;
    }
}

// 测试代码
int main() {
    std::vector<int> array = {2, 5, 8, 1, 3, 7, 9, 10};
    int mid = (array.size() - 1) / 2;

    // 合并两个有序序列 [2, 5, 8] 和 [1, 3, 7, 9, 10]
    merge(array, 0, mid, array.size() - 1);

    std::cout << "Merged array is \n";
    for (int num : array)
        std::cout << num << " ";
    std::cout << std::endl;

    return 0;
}

代码说明

  1. merge 函数

    1. 参数arr 是待排序的数组,left 是左子数组的起始索引,mid 是左右子数组的分界点,right 是右子数组的结束索引。
    2. 步骤
      1. 创建并初始化两个临时数组 LR,分别存储左子数组和右子数组的元素。
      2. 使用双指针法将两个子数组合并到原数组中。
      3. 处理任何剩余的元素,将其直接复制到原数组中。
  2. main 函数

    1. 创建一个示例数组并设定中间点。
    2. 调用 merge 函数合并两个有序子数组。
    3. 输出合并后的数组。

 快捷跳转: 


生命不息,学习不止,若有不正确的地方,欢迎指正。

  • 3
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值