首页 > 编程语言 >【归并排序】之C++实现

【归并排序】之C++实现

时间:2023-12-26 23:00:56浏览次数:36  
标签:归并 int 复杂度 合并 C++ 数组 排序

描述

归并排序是一种经典的排序算法,采用分治的思想。 归并排序是一种基于分治思想的经典排序算法。它将待排序的数组不断地分成两个子数组,直到每个子数组只有一个元素。然后,对每个子数组进行归并排序,即不断地将两个有序的子数组合并成一个有序的数组。最终,所有子数组都合并成一个有序的数组,完成排序。

归并排序的核心操作是合并两个有序数组。合并时,从两个数组的开头依次比较元素的大小,将较小的元素放入结果数组中,直到其中一个数组的元素全部放入结果数组中。然后,将剩余的元素直接放入结果数组中,得到一个有序的合并数组。

归并排序是一种稳定的排序算法,即相等元素的相对位置在排序前后保持一致。它适用于对大规模数据进行排序,但由于递归操作和额外的空间消耗,对于小规模数据可能会有一定的性能损失。在实际应用中,可以根据数据规模和性能需求选择合适的排序算法。

实现思路

  1. 将待排序的数组不断地分成两个子数组,直到每个子数组只有一个元素。
  2. 对每个子数组进行归并排序,即不断地将两个有序的子数组合并成一个有序的数组。
  3. 重复上述步骤,直到所有子数组都合并成一个有序的数组。

图解

image.png

事件复杂度

归并排序的时间复杂度为O(nlogn),其中n表示待排序数组的长度。它的分治思想保证了每次都将待排序数组二分,所以排序的时间复杂度是稳定的。

空间复杂度

归并排序的空间复杂度为O(n),其中n表示待排序数组的长度。在归并排序的过程中,需要创建一个与原数组长度相同的临时数组来存放排序结果。

在归并排序的合并阶段,需要将两个子数组按照顺序合并到临时数组中。这个临时数组的长度与原数组长度相同,因为最差情况下,两个子数组的元素都要合并到临时数组中。

在递归过程中,每次将原数组分成两个子数组,然后对子数组进行排序。这样,递归的深度为logn,每层递归需要O(n)的额外空间来存放临时数组。

综上所述,归并排序的空间复杂度为O(n)。

示例

#include <iostream>
using namespace std;

// 合并两个有序数组
void merge(int arr[], int low, int mid, int high) {
    int n1 = mid - low + 1; // 左半部分数组的长度
    int n2 = high - mid;    // 右半部分数组的长度

    int leftArr[n1], rightArr[n2]; // 临时存放左右两个子数组的数组

    // 将数据复制到临时数组
    for (int i = 0; i < n1; i++) {
        leftArr[i] = arr[low + i];
    }
    for (int j = 0; j < n2; j++) {
        rightArr[j] = arr[mid + 1 + j];
    }

    // 将两个子数组合并为一个有序数组
    int i = 0, j = 0, k = low;
    while (i < n1 && j < n2) {
        if (leftArr[i] <= rightArr[j]) {
            arr[k] = leftArr[i];
            i++;
        } else {
            arr[k] = rightArr[j];
            j++;
        }
        k++;
    }

    // 将剩余的元素复制到arr中
    while (i < n1) {
        arr[k] = leftArr[i];
        i++;
        k++;
    }
    while (j < n2) {
        arr[k] = rightArr[j];
        j++;
        k++;
    }
}

// 归并排序
void mergeSort(int arr[], int low, int high) {
    if (low < high) {
        int mid = (low + high) / 2;
        mergeSort(arr, low, mid);        // 对左半部分数组进行排序
        mergeSort(arr, mid + 1, high);   // 对右半部分数组进行排序
        merge(arr, low, mid, high);      // 合并左右两个有序数组
    }
}

int main() {
    int arr[] = {5, 2, 7, 1, 3, 6, 4};
    int n = sizeof(arr) / sizeof(arr[0]);

    mergeSort(arr, 0, n - 1);

    cout << "排序结果:";
    for (int i = 0; i < n; i++) {
        cout << arr[i] << " ";
    }
    cout << endl;

    return 0;
}

注意事项

  1. 归并排序是稳定的排序算法,即相等元素的相对位置在排序前后保持一致。
  2. 归并排序的空间复杂度较高,需要额外的空间来存放临时数组。
  3. 在实现过程中,需要注意边界条件的处理,以避免数组越界错误。

使用技巧

  1. 归并排序适用于对大规模数据进行排序,因为其时间复杂度是稳定的。
  2. 如果待排序数组长度较小,可以使用其他简单的排序算法,如插入排序或选择排序。

结论

每天都冒出很多念头,那些不死的才叫做梦想

标签:归并,int,复杂度,合并,C++,数组,排序
From: https://blog.51cto.com/u_16417016/8988793

相关文章

  • C++ Qt开发:数据库与TableView多组件联动
    Qt是一个跨平台C++图形界面开发库,利用Qt可以快速开发跨平台窗体应用程序,在Qt中我们可以通过拖拽的方式将不同组件放到指定的位置,实现图形化开发极大的方便了开发效率,本章将重点介绍TableView组件与数据库联动的常用方法及灵活运用。在Qt中,通常我们不会在TableView等组件中保存数......
  • T397291 【模板】拓扑排序(加强版)
    原题链接思路找到所有入度为零的点,然后消除其子节点的入度,再把入度为零的点塞入队列中为什么可以这么做呢?一个点能弹出队列,其父节点一定比他先入队,以此类推。。代码#include<bits/stdc++.h>usingnamespacestd;vector<int>G[100005];intin[100005]={0};intmain(){......
  • 按不同列排序
    问题:数据源三列,返回第一、二列按数据源第二列降序排序显示第一、二列; 第三、四列按数据源第三列降序排序显示第一、三列。函数公式解决:=CHOOSECOLS(SORT($A2:$C27,COLUMN(D1)/2,-1),IF(MOD(COLUMN(A1),2),1,COLUMN(C1)/2))Sort部分第一参数是数据源,第三参数-1表示降序排序。第二参......
  • QT 中配置 64位kafka ,c++
    在MSYS2下,执行$pacman-Smingw32/mingw-w64-i686-librdkafkamingw64/mingw-w64-x86_64-librdkafka即可获得二进制库、头文件和动态链接库。文件路径实例,D:\msys64\mingw64下找文件即可:D:\msys64\mingw64\lib\librdkafka++.dll.a 在工程文件中创建文件夹thirdparty/librdkaf......
  • 有什么好用的C/C++源代码混淆工具?
    开始使用ipaguard前言iOS加固保护是直接针对iosipa二进制文件的保护技术,可以对iOSAPP中的可执行文件进行深度混淆、加密。使用任何工具都无法逆向、破解还原源文件。对APP进行完整性保护,防止应用程序中的代码及资源文件被恶意篡改。IpaGuard通过修改ipa文件中的macho文件......
  • C++ Qt开发:QSqlDatabase数据库组件
    Qt是一个跨平台C++图形界面开发库,利用Qt可以快速开发跨平台窗体应用程序,在Qt中我们可以通过拖拽的方式将不同组件放到指定的位置,实现图形化开发极大的方便了开发效率,本章将重点介绍QSqlDatabase数据库模块的常用方法及灵活运用。QtSQL模块是Qt框架的一部分,它提供了一组类和函数......
  • C/C++中的宏相关操作
    C++中的宏具有一些高级用法,以下是其中的一些:可变参数宏:使用...;表示可变参数,在宏里对可变参数进行操作。比如使用 __VA_ARGS__ 来代表可变参数。字符串拼接:使用# 操作符,可以将参数转换为字符串。例如,#defineSTRINGIFY(x)#x 可以将 x 转换为字符串。标记连接:使用......
  • C++U4-第10课-前缀和与差分
    学习目标 前缀和解决的问题 前缀和概念 前缀和构建方式  前缀和主要解决区间求和问题练习题1:[前缀和]【算法分析】前缀和数组s的含义是s[i]表示a[1]~a[i]的和,那么∑i=li=r​a[i]=s[r]−s[l−1]。【参考代码】#include<iostream>usin......
  • Qt/C++音视频开发61-多屏渲染/一个解码渲染到多个窗口/画面实时同步
    一、前言多屏渲染就是一个解码线程对应多个渲染界面,通过addrender这种方式添加多个绘制窗体,我们经常可以在展会或者卖电视机的地方可以看到很多电视播放的同一个画面,原理应该类似,一个地方负责打开解码播放,将画面同步传输到多个显示的地方,完全保证了画面的一致性。这样相当于复用......
  • Integer数组与int数组排序对比
    使用Arrays.sort的方法发现int数组和Integer数组的sort方法有区别Integer[]arr={1,2,3};int[]arr1={1,2,3};Arrays.sort(arr1);Arrays.sort(arr,newComparator<Integer>(){@Overridepublicintcompar......