当前位置: 首页 > article >正文

分治算法归并排序

分治算法

基本概念

把一个复杂的问题分成两个或更多的相同或相似的子问题,再把子问题分成更小的子问题…直到最后子问题可以简单的直接求解,原问题的解即子问题的解的合并。

分治法的基本步骤

分治法在每一层递归上都有三个步骤:

step1分解:将原问题分解为若干个规模较小,相互独立,与原问题形式相同的子问题;
step2解决:若子问题规模较小而容易被解决则直接解,否则递归地解各个子问题
step3合并:将各个子问题的解合并为原问题的解。

归并排序

归并排序是利用归并的思想实现的排序方法,该算法采用经典的分治)策略(分治法将问题分成一些小的问题然后递归求解,而治的阶段则将分的阶段得到的各答案"修补"在一起,即分而治之)。
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

代码如下:

#include <iostream>
using namespace std;

const int N = 1e4 + 10;
int is1[N], is2[N]; // `is1` 为主数组,`is2` 为辅助数组

// 合并两个有序子数组的函数
void merge(int low, int mid, int high) {
    int i = low, j = mid + 1, k = low; // 初始化 i, j, k 指针

    // 合并两个有序子数组
    while (i <= mid && j <= high) {
        if (is1[i] < is1[j]) {
            is2[k++] = is1[i++]; // 左子数组元素更小,拷贝到辅助数组
        }
        else {
            is2[k++] = is1[j++]; // 右子数组元素更小,拷贝到辅助数组
        }
    }

    // 处理左子数组剩余元素
    while (i <= mid) {
        is2[k++] = is1[i++];
    }

    // 处理右子数组剩余元素
    while (j <= high) {
        is2[k++] = is1[j++];
    }

    // 将辅助数组中的合并结果拷贝回主数组
    for (int i = low; i <= high; i++) {
        is1[i] = is2[i];
    }
}

// 归并排序递归函数
void mergesort(int l, int r) {
    if (l >= r) {
        return; // 如果子数组长度为1或无效,直接返回
    }

    int mid = (l + r) >> 1; // 计算中间索引
    mergesort(l, mid);      // 递归排序左半部分
    mergesort(mid + 1, r);  // 递归排序右半部分
    merge(l, mid, r);       // 合并两个有序子数组
}

int main() {
    int n;
    cin >> n; // 输入数组长度

    // 输入数组元素
    for (int i = 1; i <= n; i++) {
        cin >> is1[i];
    }

    // 归并排序
    mergesort(1, n);

    // 输出排序后的数组
    for (int i = 1; i <= n; i++) {
        cout << is1[i] << ' ';
    }
    cout << endl;

    return 0;
}

代码模板

// 合并排序函数
void merge_sort(int q[], int l, int r)
{
    // 如果子数组只有一个元素或为空,则无需排序
    if (l >= r) return;
    // 计算中间点
    int mid = l + r >> 1;
    // 递归地排序左半部分
    merge_sort(q, l, mid);
    // 递归地排序右半部分
    merge_sort(q, mid + 1, r);
    // 定义临时数组用于合并
    int k = 0, i = l, j = mid + 1;
    int tmp[r - l + 1]; // 临时数组大小为当前处理的子数组大小
    // 合并两个已排序的子数组
    while (i <= mid && j <= r)
        if (q[i] <= q[j]) tmp[k ++ ] = q[i ++ ]; // 将较小的元素放入临时数组
        else tmp[k ++ ] = q[j ++ ]; // 将较小的元素放入临时数组
    // 将左半部分剩余的元素添加到临时数组
    while (i <= mid) tmp[k ++ ] = q[i ++ ];
    // 将右半部分剩余的元素添加到临时数组
    while (j <= r) tmp[k ++ ] = q[j ++ ];
    // 将临时数组中的元素复制回原数组
    for (i = l, j = 0; i <= r; i ++, j ++ ) q[i] = tmp[j];
}

代码链接gitee

归并排序的时间复杂度为O(nlogn)


http://www.kler.cn/news/307866.html

相关文章:

  • CSP-J/S赛前知识点大全2:初赛纯靠记忆的知识点
  • Docker高级管理之compose容器编排与私有仓库的部署
  • FPGA实现串口升级及MultiBoot(四)MultiBoot简介
  • [苍穹外卖]-12Apache POI入门与实战
  • 滚雪球学SpringCloud[2.1]:服务注册中心Eureka
  • robomimic基础教程(三)——自带算法
  • 【Linux】ICMP
  • 【开端】docker基线漏洞修复
  • React-Hooks-Form 集成 Zod 校验库
  • go get -u @latest没有更新依赖模块
  • 如何通过深度学习实践来理解深度学习的核心概念
  • Ubuntu 24.04中安装virtualenv
  • QT + WebAssembly + Vue环境搭建
  • JS面试真题 part4
  • 【Spring框架精讲】进阶指南:企业级Java应用的核心框架(Spring5)
  • NX二次开发—批量导出点工具
  • html限制仅有一个音/视频可播放
  • 阿里云社区领积分自动打卡Selenium IDE脚本
  • How to see if openAI (node js) createModeration response “flagged“ is true
  • 代码随想录算法训练营第五十八天 | 拓扑排序精讲-软件构建
  • Arduino IDE离线配置第三方库文件-ESP32开发板
  • 8.JMeter+Ant(基于工具的实现接口自动化,命令行方式)
  • 常见的限流算法
  • 【C/C++】程序的构建(编译)过程概述
  • 【C++】函数重载
  • Python使用pymysql返回字典类型的数据
  • yum本地源配置
  • 基于 SpringBoot 的车辆充电桩管理系统
  • 医药|基于springboot的医药管理系统设计与实现(附项目源码+论文+数据库)
  • JAVA算法数据结构第一节稀疏矩阵