Java、通用的并行合并排序

本文介绍了一种使用Java实现的并行合并排序算法,并通过实验对比了整型和浮点型数组的排序效率。该算法利用了Fork/Join框架进行任务的分解与合并,有效地提升了大规模数据排序的性能。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

 

package thread;

import java.security.SecureRandom;
import java.util.Arrays;
import java.util.concurrent.ForkJoinPool;
import java.util.concurrent.RecursiveAction;

public class Exercise30_13 {
    public static void main(String[] args) {
        final int SIZE = 10_000_000;
        Integer[] integersList = new Integer[SIZE];             //整型数组
        for (int i = 0; i < integersList.length; i++)           //初始化赋值
            integersList[i] = new SecureRandom().nextInt(SIZE);

        //测试并行排序
        long startTime = System.currentTimeMillis();
        parallelMergeSort(integersList);
        long endTime = System.currentTimeMillis();
        System.out.println("The number of processors is " + Runtime.getRuntime().availableProcessors());
        System.out.println("The time is " + (endTime - startTime) + " milliseconds");

        //输出前100个值
        for (int i = 0; i < 100; i++)
            System.out.print(integersList[i] + " ");
        System.out.println();


        //------------------------------------------------


        Double[] doublesList = new Double[SIZE];        //double型数组
        for (int i = 0; i < doublesList.length; i++)    //初始化赋值
            doublesList[i] = new SecureRandom().nextDouble() * SIZE;

        //测试并行排序
        startTime = System.currentTimeMillis();
        parallelMergeSort(doublesList);
        endTime = System.currentTimeMillis();
        System.out.println("The number of processors is " + Runtime.getRuntime().availableProcessors());
        System.out.println("The time is " + (endTime - startTime) + " milliseconds");

        //输出前100个值
        for (int i = 0; i < 100; i++)
            System.out.printf("%6.2f", doublesList[i]);
        System.out.println();
    }

    /** 泛型并行合并排序 */
    public static <E extends Comparable<E>> void parallelMergeSort(E[] list) {
        RecursiveAction mainTask = new MergeTask<>(list);
        ForkJoinPool pool = new ForkJoinPool();
        pool.invoke(mainTask);
    }

    /** 内部类-合并排序任务类 */
    private static class MergeTask<E extends Comparable<E>> extends RecursiveAction {
        private static final int THRESHOLD = 500;       //最小门槛
        private E[] list;                               //列表

        public MergeTask(E[] list) {
            this.list = list;
        }

        @Override
        protected void compute() {
            if (list.length < THRESHOLD)    //列表长度小于最小门槛,执行顺序排序
                Arrays.sort(list);
            else {      //执行并行排序
                E[] firstHalf = (E[])(new Comparable[list.length / 2]);     //前一半子数组
                System.arraycopy(list, 0, firstHalf, 0, firstHalf.length);

                int secondHalfLength = list.length - list.length / 2;
                E[] secondHalf = (E[])(new Comparable[secondHalfLength]);   //后一半子数组
                System.arraycopy(list, list.length / 2, secondHalf, 0, secondHalfLength);

                //分解调用子数组
                invokeAll(new MergeTask<>(firstHalf), new MergeTask<>(secondHalf));
                merge(firstHalf, secondHalf, list);     //合并数组
            }
        }

        /** 合并数组 */
        private void merge(E[] list1, E[] list2, E[] temp) {
            int current1, current2, current3;   //代表数组下标
            current1 = current2 = current3 = 0;

            //将 list1 和 list2 的值添加进 temp 数组
            while (current1 < list1.length && current2 < list2.length)
                temp[current3++] = list1[current1].compareTo(list2[current2]) < 0 ?
                        list1[current1++] : list2[current2++];

            while (current1 < list1.length)     //添加剩余的 list1 的元素
                temp[current3++] = list1[current1++];
            while (current2 < list2.length)      //添加剩余的 list2 的元素
                temp[current3++] = list2[current2++];
        }
    }
}

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值