图解Java经典算法归并排序的原理与实现

图解Java经典算法归并排序的原理与实现

算法原理

归并排序是一种基于分治思想的排序算法,它将一个大的问题分解成若干个子问题,然后将子问题拆分到足够小的规模,最后对每个小问题进行解决,最终合并所有解决得到原始问题的解决方案。归并排序的执行过程可以简单地描述为两个步骤,分别为“分”和“治”。

归并排序的第一个步骤是分解,它将原始数组分解成若干个子数组,每个子数组包含 n/2 个元素的子问题。这个过程一直重复直到每个子数组包含一个或零个元素。为了更好地说明这个过程,下面是一个示例:

假设我们有以下未排序的数组:

[23, 1, 45, 78, 87, 56, 12, 57]

我们使用归并排序对该数组进行排序,这个过程可以分成以下几个步骤:

  1. 分解:将原始数组分解成若干个子数组

    [23, 1, 45, 78, 87, 56, 12, 57] -> [23, 1, 45, 78] [87, 56, 12, 57]
    [23, 1, 45, 78] -> [23, 1] [45, 78]
    [23, 1] -> [23] [1]
    [45, 78] -> [45] [78]
    [87, 56, 12, 57] -> [87, 56] [12, 57]
    [87, 56] -> [87] [56]
    [12, 57] -> [12] [57]

  2. :合并每个子数组,将它们按照从小到大的顺序组合起来,获得最终的排序结果

    [23] [1] -> [1, 23]
    [45] [78] -> [45, 78]
    [87] [56] -> [56, 87]
    [12] [57] -> [12, 57]
    [1, 23] [45, 78] -> [1, 23, 45, 78]
    [12, 57] [56, 87] -> [12, 56, 57, 87]
    [1, 23, 45, 78] [12, 56, 57, 87] -> [1, 12, 23, 45, 56, 57, 78, 87]

算法实现

下面是归并排序的Java代码实现。在本示例中,mergeSort 方法接收一个整数类型的数组作为输入,并返回一个已排序的数组。

public class MergeSort {
    public static void main(String[] args) {
        int[] arr = {23, 1, 45, 78, 87, 56, 12, 57};
        int[] sortedArr = mergeSort(arr);
        System.out.println(Arrays.toString(sortedArr));
    }

    public static int[] mergeSort(int[] arr) {
        if (arr.length <= 1) {
            return arr;
        }

        int[] left = new int[arr.length / 2];
        int[] right = new int[arr.length - left.length];

        System.arraycopy(arr, 0, left, 0, left.length);
        System.arraycopy(arr, left.length, right, 0, right.length);

        left = mergeSort(left);
        right = mergeSort(right);

        return merge(left, right);
    }

    private static int[] merge(int[] left, int[] right) {
        int[] result = new int[left.length + right.length];
        int leftIdx = 0;
        int rightIdx = 0;
        int resIdx = 0;

        while (leftIdx < left.length && rightIdx < right.length) {
            if (left[leftIdx] < right[rightIdx]) {
                result[resIdx++] = left[leftIdx++];
            } else {
                result[resIdx++] = right[rightIdx++];
            }
        }

        while (leftIdx < left.length) {
            result[resIdx++] = left[leftIdx++];
        }

        while (rightIdx < right.length) {
            result[resIdx++] = right[rightIdx++];
        }

        return result;
    }
}

在上面的实现中,我们使用了递归的方式实现了分治的过程。当传入的数组小于等于一个元素时,我们直接返回该数组,否则,我们将该数组分成 leftright 两个数组,然后分别对它们调用 mergeSort 方法,递归地将 leftright 拆分直到长度为 1。在每次递归结束后,我们将 leftright 合并到同一个数组里面,并按照大小顺序排序。

示例说明

示例 1:普通数组排序

下面是一个普通的未排序数组:

[23, 1, 45, 78, 87, 56, 12, 57]

我们使用上面给出的 MergeSort Java类对该数组进行排序,最终排序结果为:

[1, 12, 23, 45, 56, 57, 78, 87]

示例 2:带有重复元素的数组排序

下面是另一个未排序的数组,里面包含重复元素:

[23, 1, 12, 78, 87, 56, 12, 57]

我们使用 MergeSort 对该数组进行排序,最终会得到以下结果:

[1, 12, 12, 23, 56, 57, 78, 87]

正如我们所期望的,该算法能够正确地处理重复元素,而不会对重复元素顺序进行错误的调整。

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:图解Java经典算法归并排序的原理与实现 - Python技术站

(0)
上一篇 2023年5月19日
下一篇 2023年5月19日

相关文章

  • 基于Java中两种jersey文件上传方式

    以下是关于Java中使用Jersey实现文件上传的两种方法的详细攻略: 1. 使用FormDataMultiPart方式上传文件 实现步骤 添加Jersey依赖 在pom.xml中添加以下依赖: <dependency> <groupId>org.glassfish.jersey.media</groupId> <a…

    Java 2023年5月20日
    00
  • SpringMVC实现Controller的三种方式总结

    以下是关于“SpringMVC实现Controller的三种方式总结”的完整攻略,其中包含两个示例。 SpringMVC实现Controller的三种方式总结 SpringMVC是一个基于Java的Web框架,它可以帮助我们快速开发Web应用程序。Controller是SpringMVC中的一个组件,它用于处理HTTP请求。本文将介绍SpringMVC实现C…

    Java 2023年5月17日
    00
  • Java之SpringBoot实现基本增删改查(前后端分离版)

    Java之SpringBoot实现基本增删改查(前后端分离版)攻略 简介 本篇攻略主要介绍如何使用SpringBoot实现前后端分离模式下的基本增删改查操作。在本文中,我们将使用MySQL数据库和Vue.js作为前端技术栈。此外,后端所使用的工具主要有SpringBoot、MyBatis和Swagger。在完成本文所述内容之前,请确保你已完成以下几个环节: …

    Java 2023年5月15日
    00
  • maven profile动态选择配置文件详解

    下面是本人为你准备的maven profile动态选择配置文件的攻略,希望能帮助到你。 什么是maven profile Maven Profile是Maven中的一个重要概念,它定义了一组配置的集合,用来指定开发、测试和生产环境下使用不同的配置。通过设置不同的Profile,可以实现在不同环境下对应用程序的多个设置的更改。 Maven Profile的配置…

    Java 2023年6月2日
    00
  • Spring Boot 实例代码之通过接口安全退出

    下面我将详细讲解Spring Boot实例代码之通过接口安全退出的攻略。 1. 确认需求 在开始编写代码之前,需要确认需求。根据题目要求,我们需要编写一个接口,让用户可以通过接口安全退出系统。 2. 编写代码 2.1. 添加依赖 首先,在pom.xml文件中添加Spring Security的依赖: <dependency> <groupI…

    Java 2023年6月3日
    00
  • Java的值传递和引用传递

    值传递不会改变本身,引用传递(如果传递的值需要实例化到堆里)如果发生修改了会改变本身。 1.基本数据类型都是值传递 package com.example.basic; public class Test { public static void main(String[] args) { int a=10; modify(a); System.out.pr…

    Java 2023年4月20日
    00
  • Java代码读取properties配置文件

    读取properties配置文件 package com.easycrud.utils; import java.io.IOException; import java.io.InputStream; import java.util.Iterator; import java.util.Map; import java.util.Properties; i…

    Java 2023年5月2日
    00
  • SpringBoot应用快速部署到K8S的详细教程

    将Spring Boot应用快速部署到Kubernetes(K8S)是一项非常有用的技能,可以帮助开发人员更快地将应用程序部署到生产环境中。以下是Spring Boot应用快速部署到K8S的详细攻略: 1. 准备工作 在开始之前,需要完成以下准备工作: 安装Docker和Kubernetes 创建一个Docker镜像仓库 创建一个Kubernetes集群 2…

    Java 2023年5月14日
    00
合作推广
合作推广
分享本页
返回顶部