首页 > 其他分享 >归并排序的学习

归并排序的学习

时间:2024-11-30 22:54:48浏览次数:10  
标签:10 归并 27 43 学习 38 82 排序

归并排序

思想:
归并的本质也是分治,不过不同于快速排序,它在将大问题分成小问题之后最后需要将小问题合并成最终的排序结果。

#include<iostream>
using namespace std;

const int N = 1e6+10;

int n;
int q[N],tmp[N];

void merge_sort(int q[], int l, int r) {
    if (l >= r) return;  // 递归基准:如果子数组只有一个元素或为空,不需要排序。
    
    int mid = (r + l) / 2;  // 找到数组的中间索引
    merge_sort(q, l, mid);  // 递归排序左半部分
    merge_sort(q, mid + 1, r);  // 递归排序右半部分

    int k = 0, i = l, j = mid + 1;
    while (i <= mid && j <= r) {
        // 合并操作:从两个已排序的子数组中分别取出最小的元素放入临时数组 tmp
        if (q[i] < q[j]) {
            tmp[k++] = q[i++];
        } else {
            tmp[k++] = q[j++];
        }
    }

    // 将剩余的元素复制到 tmp 中
    while (i <= mid) tmp[k++] = q[i++];
    while (j <= r) tmp[k++] = q[j++];

    // 将 tmp 中排好序的元素复制回原数组 q 中
    for (i = l, j = 0; i <= r; i++, j++) {
        q[i] = tmp[j];
    }
}
int main() {
    scanf("%d", &n);  // 输入数组的大小
    for (int i = 0; i < n; i++) scanf("%d", &q[i]);  // 输入数组的元素

    merge_sort(q, 0, n - 1);  // 调用归并排序函数,对数组进行排序

    for (int i = 0; i < n; i++) printf("%d\t", q[i]);  // 输出排序后的数组
    return 0;
}

6. 举例说明:
假设有一个数组 q = [38, 27, 43, 3, 9, 82, 10],我们进行归并排序。

第一次分解: 数组被分成两部分 [38, 27, 43] 和 [3, 9, 82, 10]。

递归分解到最小: 每个子数组继续分解,直到子数组长度为1:

[38, 27, 43] 分解成 [38], [27, 43],再分解为 [27], [43]。
[3, 9, 82, 10] 分解成 [3, 9], [82, 10],再分解为 [3], [9] 和 [82], [10]。
合并: 经过递归合并后,数组逐步恢复为有序状态:

合并 [27] 和 [43],得到 [27, 43]。
合并 [3] 和 [9],得到 [3, 9]。
合并 [82] 和 [10],得到 [10, 82]。
合并 [38] 和 [27, 43],得到 [27, 38, 43]。
合并 [3, 9] 和 [10, 82],得到 [3, 9, 10, 82]。
最终合并: 最后,合并 [27, 38, 43] 和 [3, 9, 10, 82],得到排序好的数组 [3, 9, 10, 27, 38, 43, 82]。

时间复杂度

归并排序的时间复杂度为 O(n log n),其中:
log n 是由于每次将数组分为两部分。
n 是因为每一层递归都需要遍历一次整个数组来进行合并。
所以,在最坏情况下,归并排序的时间复杂度是 O(n log n),对于任何情况都稳定在这个时间复杂度。

标签:10,归并,27,43,学习,38,82,排序
From: https://www.cnblogs.com/RedSenior/p/18578904

相关文章

  • 堆排序(下标0/1)
    0  void SiftHeap(int r[], int k, int n) {    int i = k;     int j = 2 * i + 1;  // 置i为要筛的结点,j为i的左孩子    while (j < n) {  // 筛选还没有进行到叶子    if (j + 1 < n && r[j] < r[j + 1]) j++......
  • 【机器学习】L1与L2正则化的深度解读:如何平衡模型复杂度与性能
    L1与L2正则化的深度解读:如何平衡模型复杂度与性能1.引言:过拟合问题1.1什么是过拟合?1.2为什么会出现过拟合?主要原因:1.3正则化的基本思想2.L1正则化深度解析2.1数学表达式2.2L1正则化的特性1.稀疏解的产生2.优化特性3.权重更新规则3.L2正则化深度解析3.1数......
  • 机器学习策略Ⅰ
    机器学习策略Ⅰ在构建一个好的监督学习系统时,通常需要确保以下四个方面:系统需要在训练集上能够很好地拟合数据,达到某种可接受的性能水平(如接近人类水平)。如果训练集表现不好,可以使用更大的模型(深度神经网络)、改进优化算法(Adam)、增加训练时间或数据量。系统还需要在验证集上......
  • 前端学习二
    CSS语法基础JavaScript入门......
  • 【速成】LLM大模型最新学习路线—从入门到实战!
    大语言模型学习路线:从入门到实战在人工智能领域,大语言模型(LargeLanguageModels,LLMs)正迅速成为一个热点话题。本学习路线旨在为有基本Python编程和深度学习基础的学习者提供一个清晰、系统的大模型学习指南,帮助你在这一领域快速成长。前排提示,文末有大模型AGI-CSDN独......
  • ROS2 系列学习教程(总目录)
    ROS2Learning一、ROS2简介1.1ROS2简介及学习资源汇总二、ROS2基础2.1ROS2安装详细教程(以Humble为例)2.2ROS2构建系统colcon介绍、安装与使用2.3ROS2与ROS1编码方式对比ROS2与ROS1编码方式对比(C++实现)ROS2与ROS1编码方式对比(Python实现)2.4......
  • 快速排序的学习
    快速排序思想:不同于归并,快速排序的本质是分治,且一直分,分到最小。即通过递归选中间值x将待排序的内容分为左右两个待排序区域。一直递归排序,将左边的都变成小于等于q[x]的,右边的值都大于等于q[x]。一直分分分到最小————即左右只有一个值。代码如下#include<iostream>using......
  • 技术框架对MyBatis调试信息的学习
    MyBatis开启调试信息在Maven工程的resources/pom.xml中导入log4j依赖包<!--导入log4j日志依赖包--><dependency><groupId>org.slf4j</groupId><artifactId>slf4j-log4j12</artifactId><version>1.7.5</version></depende......
  • 【机器学习算法】XGBoost原理
    一、基本内容基本内容:GBDT的基础上,在损失函数上加入树模型复杂度的正则项与GBDT一样,也是使用新的弱学习器拟合残差(当前模型负梯度,残差方向)GBDT损失函数\[Loss=\sum_{i=1}^{N}L(y_i,y_i^{t})\]XGboost损失函数\[Loss=\sum_{i=1}^{S}L(y_i,y_i^{t})+\sum_{j=1......
  • 机器学习模型从理论到实战|【005-决策树与随机森林】客户流失预测
    决策树与随机森林:从可解释性到集成方法决策树和随机森林是机器学习中常见的两种算法,它们在分类和回归任务中广泛应用,尤其在处理具有复杂非线性关系的数据时具有显著优势。决策树具有较好的可解释性,而随机森林作为一种集成学习方法,在提高模型准确性和鲁棒性方面表现出色。......