导读:本期聚焦于小伙伴创作的《Java如何实现归并排序的自定义数组切片与多路归并策略》,敬请观看详情,探索知识的价值。以下视频、文章将为您系统阐述其核心内容与价值。如果您觉得《Java如何实现归并排序的自定义数组切片与多路归并策略》有用,将其分享出去将是对创作者最好的鼓励。

归并排序的核心思想是分治,传统实现多采用二路归并,将数组拆分为两个子数组递归排序后合并。但在处理大规模数据或者需要适配特定分片规则的场景下,自定义数组切片结合多路归并可以更灵活地满足需求,本文将详细介绍Java中实现该策略的完整方法。

Java如何实现归并排序的自定义数组切片与多路归并策略

核心思路说明

整个实现过程分为三个核心步骤:首先是自定义数组切片,根据设定的切片大小或者规则,将原始无序数组拆分为多个子数组,对每个子数组单独进行排序;然后是多路归并准备,将所有排好序的子数组作为归并的输入源;最后是执行多路归并,每次从所有子数组的当前头部元素中选取最小的,放入结果数组,直到所有子数组的元素都被取完。

自定义数组切片实现

我们首先实现自定义切片逻辑,这里支持两种切片模式,一种是按固定长度切片,另一种是按指定切分点切片,代码如下:

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

public class MergeSortDemo {
    // 按固定长度切片,返回切片后的子数组列表
    private static List<int[]> sliceArrayByLength(int[] arr, int sliceLength) {
        List<int[]> sliceList = new ArrayList<>();
        if (arr == null || arr.length == 0) {
            return sliceList;
        }
        int start = 0;
        while (start < arr.length) {
            int end = Math.min(start + sliceLength, arr.length);
            int[] slice = Arrays.copyOfRange(arr, start, end);
            // 对每个子数组先进行排序
            Arrays.sort(slice);
            sliceList.add(slice);
            start = end;
        }
        return sliceList;
    }

    // 按指定切分点切片,切分点数组存放每个切片的结束索引(不包含)
    private static List<int[]> sliceArrayByPoints(int[] arr, int[] splitPoints) {
        List<int[]> sliceList = new ArrayList<>();
        if (arr == null || arr.length == 0) {
            return sliceList;
        }
        int start = 0;
        for (int end : splitPoints) {
            if (end <= start || end > arr.length) {
                continue;
            }
            int[] slice = Arrays.copyOfRange(arr, start, end);
            Arrays.sort(slice);
            sliceList.add(slice);
            start = end;
        }
        // 处理最后一个切片
        if (start < arr.length) {
            int[] lastSlice = Arrays.copyOfRange(arr, start, arr.length);
            Arrays.sort(lastSlice);
            sliceList.add(lastSlice);
        }
        return sliceList;
    }
}

多路归并实现逻辑

多路归并需要同时维护多个子数组的当前遍历位置,每次选取最小值后更新对应子数组的指针,实现代码如下:

import java.util.PriorityQueue;

public class MergeSortDemo {
    // 多路归并方法,输入排好序的子数组列表,返回合并后的完整有序数组
    private static int[] multiWayMerge(List<int[]> sortedSlices) {
        if (sortedSlices == null || sortedSlices.isEmpty()) {
            return new int[0];
        }
        // 优先队列存储每个子数组的当前元素和对应的数组索引、元素索引
        PriorityQueue<Node> queue = new PriorityQueue<>((a, b) -> a.value - b.value);
        // 初始化优先队列,加入每个子数组的第一个元素
        for (int i = 0; i < sortedSlices.size(); i++) {
            int[] slice = sortedSlices.get(i);
            if (slice.length > 0) {
                queue.add(new Node(slice[0], i, 0));
            }
        }
        int totalLength = sortedSlices.stream().mapToInt(arr -> arr.length).sum();
        int[] result = new int[totalLength];
        int index = 0;
        while (!queue.isEmpty()) {
            Node current = queue.poll();
            result[index++] = current.value;
            int nextIdx = current.elementIdx + 1;
            int[] currentSlice = sortedSlices.get(current.sliceIdx);
            if (nextIdx < currentSlice.length) {
                queue.add(new Node(currentSlice[nextIdx], current.sliceIdx, nextIdx));
            }
        }
        return result;
    }

    // 内部节点类,记录当前元素值、所属子数组索引、元素在子数组中的索引
    static class Node {
        int value;
        int sliceIdx;
        int elementIdx;

        Node(int value, int sliceIdx, int elementIdx) {
            this.value = value;
            this.sliceIdx = sliceIdx;
            this.elementIdx = elementIdx;
        }
    }
}

完整调用示例

我们将切片和归并逻辑组合起来,完成整个排序流程,示例如下:

public class MergeSortDemo {
    public static void main(String[] args) {
        int[] originalArray = {5, 2, 7, 1, 9, 3, 8, 4, 6};
        // 按固定长度3切片
        List<int[]> slices = sliceArrayByLength(originalArray, 3);
        System.out.println("切片后的子数组:");
        for (int[] slice : slices) {
            System.out.println(Arrays.toString(slice));
        }
        // 多路归并
        int[] sortedArray = multiWayMerge(slices);
        System.out.println("最终排序结果:" + Arrays.toString(sortedArray));
    }
}

复杂度分析

假设原始数组长度为n,切片后共有k个子数组,每个子数组平均长度为m,满足n = k * m。切片阶段对每个子数组排序的时间复杂度为O(k * m log m) = O(n log m),多路归并阶段使用优先队列,每次操作时间复杂度为O(log k),总共有n个元素,因此归并阶段时间复杂度为O(n log k),整体时间复杂度接近O(n log n)。空间复杂度方面,需要存储切片数组和优先队列,整体为O(n)。

注意事项

  • 自定义切片时需要注意切分点的合法性,避免出现索引越界的问题
  • 多路归并的优先队列初始容量可以设置为子数组的数量,减少扩容开销
  • 如果子数组已经有序,可以跳过子数组的排序步骤,直接进行归并,提升效率

Java归并排序数组切片多路归并排序算法修改时间:2026-07-01 12:30:39

免责声明:​ 已尽一切努力确保本网站所含信息的准确性。网站内容多为原创整理与精心编撰,观点力求客观中立。本站旨在免费分享,内容仅供个人学习、研究或参考使用。若引用了第三方作品,版权归原作者所有。如内容涉及您的权益,请联系我们处理。
内容垂直聚焦
专注技术核心技术栏目,确保每篇文章深度聚焦于实用技能。从代码技巧到架构设计,为用户提供无干扰的纯技术知识沉淀,精准满足专业提升需求。
知识结构清晰
覆盖从开发到部署的全链路。AI、前端、编程、数据库、服务器、建站、系统层层递进,构建清晰学习路径,帮助用户系统化掌握开发与运维所需的核心技术。
深度技术解析
拒绝泛泛而谈,深入技术细节与实践难点。无论是数据库优化还是服务器配置,均结合真实场景与代码示例进行剖析,致力于提供可直接应用于工作的解决方案。
专业领域覆盖
精准对应开发生命周期。从前端界面到后端编程,从数据库操作到服务器运维,形成完整闭环,一站式满足全栈工程师和运维人员的技术需求。
即学即用高效
内容强调实操性,步骤清晰、代码完整。用户可根据教程直接复现和应用于自身项目,显著缩短从学习到实践的距离,快速解决开发中的具体问题。
持续更新保障
专注既定技术方向进行长期、稳定的内容输出。确保各栏目技术文章持续更新迭代,紧跟主流技术发展趋势,为用户提供经久不衰的学习价值。