c++ 归并排序

        归并排序是一种遵循分而治之方法的排序算法。它的工作原理是递归地将输入数组划分为较小的子数组并对这些子数组进行排序,然后将它们合并在一起以获得排序后的数组。

        简单来说,归并排序的过程就是将数组分成两半,对每一半进行排序,然后将已排序的两半合并在一起。重复这个过程,直到整个数组排序完毕。

归并排序算法

归并排序是如何工作的?
        归并排序是一种流行的排序算法,以其高效和稳定而闻名。它遵循分而治之的方法对给定的元素数组进行排序。

以下是合并排序如何工作的分步说明:
        1、划分:递归地将列表或数组划分为两半,直到不能再划分为止。
        2、征服:使用合并排序算法对每个子数组进行单独排序。
        3、合并:已排序的子数组按排序顺序合并在一起。该过程将继续,直到两个子数组中的所有元素都已合并。

归并排序示意图:
让我们使用归并排序对数组或列表[38, 27, 43, 10]进行排序 

让我们看看上面例子的工作原理:
划分:
        [38, 27, 43, 10]分为[38, 27 ] 和[43, 10]。
        [38, 27]分为[38]和[27]。
        [43, 10]分为[43]和[10]。

征服:
        [38]已经排序。
        [27]已经排序。
        [43]已经排序。
        [10]已经排序。

合并:
        合并[38]和[27]得到[27, 38]。
        合并[43]和[10]得到[10,43]。
        合并[27, 38]和[10,43]得到最终的排序列表[10, 27, 38, 43]

因此,排序列表为[10, 27, 38, 43]。

归并排序的实现:
// C++ program for Merge Sort
#include <bits/stdc++.h>
using namespace std;

// Merges two subarrays of array[].
// First subarray is arr[begin..mid]
// Second subarray is arr[mid+1..end]
void merge(int array[], int const left, int const mid,
           int const right)
{
    int const subArrayOne = mid - left + 1;
    int const subArrayTwo = right - mid;

    // Create temp arrays
    auto *leftArray = new int[subArrayOne],
         *rightArray = new int[subArrayTwo];

    // Copy data to temp arrays leftArray[] and rightArray[]
    for (auto i = 0; i < subArrayOne; i++)
        leftArray[i] = array[left + i];
    for (auto j = 0; j < subArrayTwo; j++)
        rightArray[j] = array[mid + 1 + j];

    auto indexOfSubArrayOne = 0, indexOfSubArrayTwo = 0;
    int indexOfMergedArray = left;

    // Merge the temp arrays back into array[left..right]
    while (indexOfSubArrayOne < subArrayOne
           && indexOfSubArrayTwo < subArrayTwo) {
        if (leftArray[indexOfSubArrayOne]
            <= rightArray[indexOfSubArrayTwo]) {
            array[indexOfMergedArray]
                = leftArray[indexOfSubArrayOne];
            indexOfSubArrayOne++;
        }
        else {
            array[indexOfMergedArray]
                = rightArray[indexOfSubArrayTwo];
            indexOfSubArrayTwo++;
        }
        indexOfMergedArray++;
    }

    // Copy the remaining elements of
    // left[], if there are any
    while (indexOfSubArrayOne < subArrayOne) {
        array[indexOfMergedArray]
            = leftArray[indexOfSubArrayOne];
        indexOfSubArrayOne++;
        indexOfMergedArray++;
    }

    // Copy the remaining elements of
    // right[], if there are any
    while (indexOfSubArrayTwo < subArrayTwo) {
        array[indexOfMergedArray]
            = rightArray[indexOfSubArrayTwo];
        indexOfSubArrayTwo++;
        indexOfMergedArray++;
    }
    delete[] leftArray;
    delete[] rightArray;
}

// begin is for left index and end is right index
// of the sub-array of arr to be sorted
void mergeSort(int array[], int const begin, int const end)
{
    if (begin >= end)
        return;

    int mid = begin + (end - begin) / 2;
    mergeSort(array, begin, mid);
    mergeSort(array, mid + 1, end);
    merge(array, begin, mid, end);
}

// UTILITY FUNCTIONS
// Function to print an array
void printArray(int A[], int size)
{
    for (int i = 0; i < size; i++)
        cout << A[i] << " ";
    cout << endl;
}

// Driver code
int main()
{
    int arr[] = { 12, 11, 13, 5, 6, 7 };
    int arr_size = sizeof(arr) / sizeof(arr[0]);

    cout << "Given array is \n";
    printArray(arr, arr_size);

    mergeSort(arr, 0, arr_size - 1);

    cout << "\nSorted array is \n";
    printArray(arr, arr_size);
    return 0;
}

// This code is contributed by Mayank Tyagi
// This code was revised by Joshua Estes

输出
给定数组是
12 11 13 5 6 7

排序后的数组是
5 6 7 11 12 13

归并排序的复杂度分析:

时间复杂度:
最佳情况: O(n log n),当数组已经排序或接近排序时。
平均情况: O(n log n),当数组随机排序时。
最坏情况: O(n log n),当数组按相反顺序排序时。
空间复杂度: O(n),合并时使用的临时数组需要额外的空间。

归并排序的优点:
稳定性:归并排序是一种稳定的排序算法,这意味着它保持输入数组中相等元素的相对顺序。
保证最坏情况下的性能:归并排序的最坏情况时间复杂度为O(N logN),这意味着即使在大型数据集上它也能表现良好。
易于实现:分而治之的方法很简单。

归并排序的缺点:
空间复杂度:归并排序在排序过程中需要额外的内存来存储合并后的子数组。 
非就地:合并排序不是就地排序算法,这意味着它需要额外的内存来存储排序后的数据。这对于关注内存使用的应用程序来说可能是一个缺点。

归并排序的应用:
对大型数据集进行排序
外部排序(当数据集太大而无法容纳在内存中时)
反转计数(计算数组中反转的次数)
查找数组的中位数

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mfbz.cn/a/614893.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

车辆运动模型中LQR代码实现

一、前言 最近看到关于架构和算法两者关系的一个描述&#xff0c;我觉得非常认同&#xff0c;分享给大家。 1、好架构起到两个作用&#xff1a;合理的分解功能、合理的适配算法&#xff1b; 2、好的架构是好的功能的必要条件&#xff0c;不是充分条件&#xff0c;一味追求架构…

贝壳面试:MySQL联合索引,最左匹配原则是什么?

尼恩说在前面 在40岁老架构师 尼恩的读者交流群(50)中&#xff0c;最近有小伙伴拿到了一线互联网企业如得物、阿里、滴滴、极兔、有赞、希音、百度、网易、美团的面试资格&#xff0c;遇到很多很重要的面试题&#xff1a; 1.谈谈你对MySQL联合索引的认识&#xff1f; 2.在MySQ…

【强训笔记】day20

NO.1 思路&#xff1a;先判断能对砍几个回合&#xff0c;取最小值&#xff0c;因为回合数是整数&#xff0c;所以可能存在都大于0的情况&#xff0c;再判断一下如果都存活就再对砍一次&#xff0c;直到一家存活或者都死亡。 代码实现&#xff1a; #include<iostream>u…

即插即用篇 | YOLOv8 引入多光谱通道注意力 | 频率领域中的通道注意力网络

本改进已集成到 YOLOv8-Magic 框架。 注意力机制,尤其是通道注意力,在计算机视觉领域取得了巨大成功。许多工作聚焦于如何设计高效的通道注意力机制,同时忽略了一个基本问题,即通道注意力机制使用标量来表示通道,这很困难,因为会造成大量信息的丢失。在这项工作中,我们从…

OGG几何内核开发-BRepAlgoAPI_Fuse与BRep_Builder.MakeCompound比较

最近在与同事讨论BRepAlgoAPI_Fuse与BRep_Builder.MakeCompound有什么区别。 一、从直觉上来说&#xff0c;BRepAlgoAPI_Fuse会对两个实体相交处理&#xff0c;相交的部分会重新的生成相关的曲面。而BRep_Builder.MakeCompound仅仅是把两个实体组合成一个新的实体&#xff0c;…

【一支射频电缆的诞生】GORE 戈尔

工具连接&#xff1a; https://microwave-cablebuilder.gore.com/ 控制参数&#xff1a; 连接器&#xff1a; 欣赏

Ubuntu18.04--虚拟机配置Samba并从Windows登录

前言&#xff1a; 本文记录我自己在Windows上安装 Virtualbox &#xff0c;并在Virtualbox中安装 Ubuntu-18.04 虚拟机&#xff0c;在Ubuntu-18.04虚拟机里安装配置Smaba服务器&#xff0c;从 Windows 宿主系统上访问虚拟机共享samba目录的配置命令。 引用: N/A 正文 虚拟…

《Python编程从入门到实践》day25

# 昨日知识点回顾 如何创建多行外星人 碰撞结束游戏 创建game_stats.py跟踪统计信息 # 今日知识点学习 第14章 记分 14.1 添加Play按钮 14.1.1 创建Button类 import pygame.font# button.py class Button:def __init__(self, ai_game, msg):"""初始化按钮…

【GESP】2023年12月图形化二级 -- 小杨报数

小杨报数 【题目描述】 小杨需要从 1 1 1到 N N N报数。在报数过程中&#xff0c;小杨希望跳过 M M M的倍数。例如&#xff0c;如果 N 5 N5 N5&#xff0c; M 2 M2 M2&#xff0c;那么小杨就需要依次报出 1 1 1&#xff0c; 3 3 3&#xff0c; 5 5 5。 默认小猫角色和白色背…

zblog中用户中心-邀请码注册插件的导出功能补充

自己加了一个导出未使用的邀请码功能&#xff0c;可惜我不是入驻作者&#xff0c;没有权限发布&#xff0c;之前被一条大河拒了&#xff0c;他说我抄他代码&#xff0c;不给我过审还冷嘲热讽&#xff0c;我一气之下&#xff0c;就没继续申请了&#xff0c;话说我是专业搞java开…

Unity引擎是什么?有哪些优点

大家好&#xff0c;我是咕噜土豆&#xff0c;很高兴又和大家见面了。今天我们一起来了解一下Unity引擎和它有哪些优点。 首先带大家了解什么是Unity引擎 Unity引擎是一款由Unity Technologies开发的跨平台游戏开发引擎&#xff0c;广泛用于创建2D和3D游戏以及其他交互式内容&…

ADS1220芯片利用自身温度传感器测试自身温度

一、简介 ADS1220 内部集成了一个精密温度传感器&#xff0c;通过将寄存器的TS位置1可使能温度传感器模式。 在温度传感器模式下&#xff0c; 配置寄存器 0 的设置不产生任何影响&#xff0c;该器件使用内部基准进行测量&#xff0c;与所选基准电压源无关。 温度读数过程与模拟…

SELECT SUM用法和ZMM008入货登记号大于可入仓量

select sum 用法示例 入货登记号大于可入仓量 之前错误的写法

德国Dürr杜尔机器人维修技巧分析

在工业生产中&#xff0c;杜尔工业机器人因其高效、精准和稳定性而备受青睐。然而&#xff0c;即便是最精良的设备&#xff0c;也难免会出现Drr机械手故障。 一、传感器故障 1. 视觉传感器故障&#xff1a;可能导致机器人无法正确识别目标物&#xff0c;影响工作效率。解决方法…

27.哀家要长脑子了!---栈与队列

1.739. 每日温度 - 力扣&#xff08;LeetCode&#xff09; 用单调栈的方法做&#xff1a; 从左到右遍历数组&#xff1a; 栈中存放的是下标&#xff0c;每个温度在原数组中的下标&#xff0c;从大到小排列&#xff0c;因为这样才能确保的是最近一天的升高温度 如果栈为空&am…

【Ubuntu 安装erlang】

apt-get 安装 apt-get install erlang或 源码安装 git clone https://github.com/erlang/otp.git cd otp git checkout maint-25 # current latest stable version ./configure make make install安装完后&#xff0c;验证是否成功 # 命令行输入 erl

JavaSE基础小知识Ⅱ(很容易错!!!)

1. 变量被final修饰后不能再指向其他对象&#xff0c;但可以重写 如果是引用变量被final修饰&#xff0c;那么的确如此&#xff1b; 基本变量不能重写 2. 下列代码的输出结果是&#xff1f; public class Test {static {int x 5; }static int x,y; public static void ma…

Ansible playbook

playbook playbook介绍 playbooks是ansible用于配置&#xff0c;部署&#xff0c;和管理被控节点的剧本。通过playbooks的详细描述&#xff0c;执行其中的tasks&#xff0c;可以让远端主机达到预期的状态。playbooks是由一个或多个”play”组成的列表。 当对一台机器做环境初…

【免费】在线识别通用验证码接口

模块优势价格5元1000次&#xff0c;每天免费100次api文档支持 使用量小的完全够用了 <?phpfunction Post_base64($base64_str){$url http://api.95man.com:8888/api/Http/Recog?Taken41******QK&imgtype1&len0 ; $fields array( ImgBase64>$base64_str); $ch…

MySQL系列之索引

&#x1f339;作者主页&#xff1a;青花锁 &#x1f339;简介&#xff1a;Java领域优质创作者&#x1f3c6;、Java微服务架构公号作者&#x1f604; &#x1f339;简历模板、学习资料、面试题库、技术互助 &#x1f339;文末获取联系方式 &#x1f4dd; 往期热门专栏回顾 专栏…