归并排序的思想

2023-09-19 22:33:06

归并排序是一种基于分治思想的经典排序算法。它将待排序的数组分成两个部分,然后递归地对这两个部分进行排序,最后再将排序好的两个部分归并成一个有序的数组。

具体实现过程如下:

1. 将待排序数组不断二分,直到只剩下一个元素,此时该元素就是有序的。
2. 将相邻的两个有序数组合并成一个有序数组。合并时,对于两个数组中首位元素进行比较,将较小的元素放入新数组中,直到一个数组全部放入新数组中,最后将另一个数组直接拼接到新数组的后面。
3. 重复步骤2,直到所有的数组合并成一个有序数组。

时间复杂度为O(nlogn),是稳定的排序算法,但空间复杂度为O(n),需要额外的存储空间。

python实现:

def merge_sort(arr):
    if len(arr) <= 1:
        return arr

    mid = len(arr) // 2
    left = merge_sort(arr[:mid])
    right = merge_sort(arr[mid:])

    return merge(left, right)

def merge(left, right):
    result = []
    left_index = 0
    right_index = 0

    while left_index < len(left) and right_index < len(right):
        if left[left_index] <= right[right_index]:
            result.append(left[left_index])
            left_index += 1
        else:
            result.append(right[right_index])
            right_index += 1

    result += left[left_index:]
    result += right[right_index:]

    return result

C++实现:

#include <iostream>
#include <vector>

using namespace std;

// 归并两个有序数组
void merge(vector<int>& nums, int left, int mid, int right) {
    int i = left, j = mid + 1, k = 0;
    vector<int> temp(right - left + 1);
    while (i <= mid && j <= right) {
        if (nums[i] < nums[j])
            temp[k++] = nums[i++];
        else
            temp[k++] = nums[j++];
    }
    while (i <= mid)
        temp[k++] = nums[i++];
    while (j <= right)
        temp[k++] = nums[j++];
    for (int p = 0; p < k; ++p)
        nums[left + p] = temp[p];
}

// 归并排序
void merge_sort(vector<int>& nums, int left, int right) {
    if (left < right) {
        int mid = left + (right - left) / 2;
        merge_sort(nums, left, mid);  // 排序左边子数组
        merge_sort(nums, mid + 1, right);  // 排序右边子数组
        merge(nums, left, mid, right);  // 合并有序子数组
    }
}

int main() {
    vector<int> nums = {3, 1, 4, 1, 5, 9, 2, 6, 5, 3, 5};  // 待排序数组
    merge_sort(nums, 0, nums.size() - 1);  // 归并排序
    for (int i = 0; i < nums.size(); ++i)  // 输出排序结果
        cout << nums[i] << " ";
    cout << endl;
    return 0;
}

Java实现:

 

public class MergeSort {

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

    public static void merge(int[] arr, int left, int mid, int right) {
        int[] temp = new int[right - left + 1]; // 临时数组,存放合并后的序列
        int i = left, j = mid + 1, k = 0;

        while (i <= mid && j <= right) { // 将左右两个有序序列合并
            if (arr[i] <= arr[j]) {
                temp[k++] = arr[i++];
            } else {
                temp[k++] = arr[j++];
            }
        }

        while (i <= mid) { // 将左边剩余元素填充进temp中
            temp[k++] = arr[i++];
        }

        while (j <= right) { // 将右边剩余元素填充进temp中
            temp[k++] = arr[j++];
        }

        for (int p = 0; p < temp.length; p++) { // 将temp中的元素全部拷贝到原数组中
            arr[left + p] = temp[p];
        }
    }

}

更多推荐

玫瑰代码||逐字打印字体||中秋快乐

关注微信公众号「ClassmateJie」更多惊喜等待你的发掘直接看实现效果电脑端手机端使用场景发给女神告白~提供一些文案“自从遇见你,我的世界变得不一样了。每一天都因为你而变得特别。我想告诉你,我喜欢你,不仅仅是因为你的美丽,还因为你温暖的心灵和聪明的头脑。"“我一直在寻找那个能让我心动的人,而现在我知道,那个人就是

记一次 .NET 某餐饮小程序 内存暴涨分析

一:背景1.讲故事前些天有位朋友找到我,说他的程序内存异常高,用vs诊断工具加载时间又太久,让我帮忙看一下到底咋回事,截图如下:确实,如果dump文件超过10G之后,市面上那些可视化工具分析起来会让你崩溃的,除了时间久之外这些工具大多也不是用懒加载的方式,比如dotmemory会把数据全部灌入内存,针对这种dump,你

滚雪球学Java(29):数组长度和排序算法:让你的程序更高效

🏆本文收录于「滚雪球学Java」专栏,专业攻坚指数级提升,助你一臂之力,带你早日登顶🚀,欢迎大家关注&&收藏!持续更新中,up!up!up!!前言在上一篇文章中,我们学习了数组的常用技巧和方法。本篇文章将深入探讨数组长度以及如何使用排序算法提高程序效率。摘要数组长度是数组中元素的个数,可以使用length属性获取。

Vue入门

Vue的介绍1.什么是vue?vue是一个渐进式js框架,它被设计用于构建用户界面和单页应用程序。Vue.js很容易上手,易于学习,并且是一种非常灵活的开发工具。1特点:轻量级:Vue.js的文件大小只有20KB左右,非常适合快速构建小型应用程序。双向数据绑定:Vue.js使用MVVM(Model-View-ViewM

【MATLAB第75期】#源码分享 | 基于MATLAB的不规则数据插值实现时间序列数据扩充

【MATLAB第75期】#源码分享|基于MATLAB的不规则数据插值实现时间序列数据扩充如时间数据以单位1为间隔排序,可插间隔为0.5的数据。一、实现效果1.规则间隔数据2.非规则间隔数据二、主程序代码1.插值测试效果%%清空环境变量warningoff%关闭报警信息closeall%关闭开启的图窗clear%清空变量

MySQL(3)索引实践一

一、索引下推:对于辅助的联合索引(name,age),正常情况按照最左前缀原则,SELECT*FROMuserWHEREnamelike'xiao%'ANDage=22这种情况只会走name字段索引,因为根据name字段过滤完,得到的索引行里的age是无序的,无法很好的利用索引。在MySQL5.6之前的版本,这个查询只

Matlab之并行程序设计实战教程

在本教程中,我们将介绍如何使用Matlab进行并行程序设计。我们将通过一个简单的示例来演示如何将串行代码转换为并行代码,以提高程序的执行效率。示例:计算一个数组的平方和假设我们有一个包含10000个元素的数组,我们想计算该数组的平方和。首先,我们来看看如何使用串行代码实现这个任务。%%串行代码array=1:10000

javase javaee javame

1.JavaSEJavaSE(JavaPlatform,StandardEdition):Java平台标准版。它是JavaEE和JavaME的基础,之前称为J2SE,用来开发C/S架构软件,通俗来讲,就是开发电脑桌面的应用软件、电脑上运行的软件,例如,Java应用程序开发平台Eclipse。同时也是Java的基础,Ja

阿里云服务器租用费用价格表(2023新版报价)

租用阿里云服务器怎么收费?阿里云服务器配置不同一年价格也不同,阿里云2核2G3M带宽108元一年、2核4G4M带宽297.98元12个月,云服务器u1公网带宽可选1M到5M,系统盘为ESSD云盘40GB起,CPU内存配置可选2核2G、2核4G、4核8G、8核16G等配置,还有ECS计算型c7、通用型g7和内存型r7多C

Python子进程管理与进程信息获取

1.Python子进程模块subprocesssubprocess模块允许我们启动一个新进程,并连接到它们的输入/输出/错误管道,从而获取返回值。(1)run方法首先我们来看看run方法的使用,该方法的参数如下:args:表示要执行的命令。必须是一个字符串或字符串参数列表。stdin、stdout和stderr:子进程

【UE 粒子练习】05——创建光束类型粒子

效果步骤1.新建一个材质,这里命名为“Mat_Beam”设置材质域为表面,混合模式为半透明,着色模型为无光照材质节点如下:2.新建一个粒子系统,命名为“P_Beam”打开“P_Beam”,在发射器中新建一个光束数据在必需模块中将材质改为上一步创建的材质“Mat_Beam”在“光束数据”模块中,设置光束方法为“目标”,这

热文推荐