`
worldlxy
  • 浏览: 1076 次
  • 性别: Icon_minigender_1
  • 来自: 西安
文章分类
社区版块
存档分类
最新评论

用Fork and Join实现归并排序

阅读更多
很早就知道JDK7的ForkAndJoin框架了,一直没有学习。看了官网WordCount的例子,
http://www.oracle.com/technetwork/articles/java/fork-join-422606.html
自己写一个归并排序练练手。(代码中增加的打印语句完全是为了方便理解)

import java.util.*;
import java.util.concurrent.ForkJoinPool;
import java.util.concurrent.RecursiveTask;

public class MergeSortTask extends RecursiveTask<int[]> {
    private static final String ROOT = "0";
    private static final String LEFT = "0";
    private static final String RIGHT = "1";
    private final int[] array;
    private final String serial;

    public MergeSortTask(int[] array, String serial) {
        this.array = array;
        this.serial = serial;
    }

    @Override
    protected int[] compute() {
        int length = array.length;
        if (length <= 3) {
            Arrays.sort(array);
            return array;
        }

        String leftSerial = getLeftSerial();
        String rightSerial = getRightSerial();

        int[] leftArray = Arrays.copyOfRange(array, 0, length / 2);
        int[] rightArray = Arrays.copyOfRange(array, length / 2, length);
        MergeSortTask leftTask = new MergeSortTask(leftArray, leftSerial);
        MergeSortTask rightTask = new MergeSortTask(rightArray, rightSerial);

        System.out.println(new MidArray(leftSerial, leftArray));
        System.out.println(new MidArray(rightSerial, rightArray));

        int[] leftResult = leftTask.fork().join();
        int[] rightResult = rightTask.fork().join();

        System.out.println(new MidResult(new MidArray(leftSerial, leftResult)));
        System.out.println(new MidResult(new MidArray(rightSerial, rightResult)));

        return merge(leftResult, rightResult);
    }

    private String getLeftSerial() {
        return serial + "-" + LEFT;
    }

    private String getRightSerial() {
        return serial + "-" + RIGHT;
    }

    private int[] merge(int[] leftArray, int[] rightArray) {
        int leftArrayLength = leftArray.length;
        int rightArrayLength = rightArray.length;
        int[] resultArray = new int[leftArrayLength + rightArrayLength];

        int resultIndex = 0;
        int leftIndex = 0;
        int rightIndex = 0;

        while (leftIndex < leftArrayLength && rightIndex < rightArrayLength) {
            if (leftArray[leftIndex] <= rightArray[rightIndex]) {
                resultArray[resultIndex++] = leftArray[leftIndex++];
            } else {
                resultArray[resultIndex++] = rightArray[rightIndex++];
            }
        }

        //copy left rest
        if (leftIndex < leftArrayLength) {
            System.arraycopy(leftArray, leftIndex, resultArray, 
                                 resultIndex, leftArrayLength - leftIndex);
        }
        //copy right rest
        if (rightIndex < rightArrayLength) {
            System.arraycopy(rightArray, rightIndex, resultArray, 
                                resultIndex, rightArrayLength - rightIndex);
        }

        return resultArray;
    }

    private static int[] buildTestArray(int size) {
        int[] testArray = new int[size];
        Random rand = new Random();
        for (int i = 0; i < size; i++) {
            testArray[i] = rand.nextInt(100);
        }

        return testArray;
    }

    public static void main(String[] args) {
        int[] testArray = buildTestArray(10);
        System.out.println(Arrays.toString(testArray));
        MergeSortTask mergeSorter = new MergeSortTask(testArray, ROOT);
        ForkJoinPool pool = new ForkJoinPool();
        System.out.println(Arrays.toString(pool.invoke(mergeSorter)));
    }
}

//辅助类
import java.util.Arrays;

public class MidArray {
    private final String serial;
    private final int[] result;
    private static final String INDENT = "  ";

    public MidArray(String serial, int[] result) {
        this.serial = serial;
        this.result = result;
    }

    public String toString() {
        StringBuilder sb = new StringBuilder();
        for (int i = 0; i < serial.split("-").length; i++) {
            sb.append(INDENT);
        }
        sb.append(serial).append(", is: ").append(Arrays.toString(result));

        return sb.toString();
    }
}

public class MidResult {

    private MidArray midArray;

    public MidResult(MidArray midArray) {
        this.midArray = midArray;
    }

    public String toString() {
        return midArray.toString() + " [Result]";
    }
}


一次运行的输出结果:

[71, 8, 25, 9, 4, 41, 38, 87, 45, 96]
    0-0, is: [71, 8, 25, 9, 4]
    0-1, is: [41, 38, 87, 45, 96]
      0-0-0, is: [71, 8]
      0-0-1, is: [25, 9, 4]
      0-0-0, is: [8, 71] [Result]
      0-0-1, is: [4, 9, 25] [Result]
      0-1-0, is: [41, 38]
      0-1-1, is: [87, 45, 96]
      0-1-0, is: [38, 41] [Result]
      0-1-1, is: [45, 87, 96] [Result]
    0-0, is: [4, 8, 9, 25, 71] [Result]
    0-1, is: [38, 41, 45, 87, 96] [Result]
[4, 8, 9, 25, 38, 41, 45, 71, 87, 96]
分享到:
评论

相关推荐

    fj-demo:ForkJoin可视化

    5. **并行合并排序(Parallel Merge Sort)**: 描述中提到的“基于Fork / Join的合并排序的可视化表示”是指使用ForkJoin框架实现的并行版本的归并排序。归并排序是一种分治算法,通常步骤包括:分割数组,对每个子...

    Java方法排序五百万数据

    在Java中,最基础的是`Arrays.sort()`函数,它使用了快速排序(Quick Sort)和归并排序(Merge Sort)的混合策略。对于小数组,快速排序具有很好的表现,而对于大数组,归并排序的稳定性使其成为更好的选择。然而,...

    181220010 丁豪 实验报告1

    这篇实验报告主要探讨了三种排序算法的并行化实现,包括快速排序、枚举排序和归并排序,并在实验环境中对比了串行和并行版本的性能差异。实验由181220010号学生丁豪完成,属于分布式与并行计算课程的一部分。 快速...

    java swing io 排序的几个小实例

    这些内置的方法已经实现了高效的排序算法,如快速排序和归并排序。然而,在实际开发中,有时我们需要自定义排序规则,这时可以实现Comparator接口或Comparable接口来完成。 在描述中提到的“java swing io 排序的几...

    Sorting-Algorithms:基本到中级排序算法

    3. 多线程排序:对于大数据量,可以考虑使用多线程进行并行排序,如Fork/Join框架下的ParallelSort。 三、优化策略 1. 计数排序、桶排序和基数排序:这三种非比较型排序算法在特定条件下能实现线性时间复杂度O(n)...

    CS62sophomoricParallelismAndConcurrency

    更进一步,教材探索了更高级的Fork-Join算法,包括并行前缀求和(Parallel-Prefix Sum)、打包(Pack)算法、并行快速排序(Parallel Quicksort)和并行归并排序(Parallel Mergesort)。这些算法都是在共享内存的...

    jdk-7u80-macosx-x64.dmg.zip

    2. **多路归并排序**:JDK7在`Arrays.sort()`方法中实现了多路归并排序,提高了数组排序的性能。 3. **try-with-resources**:此特性使得资源管理更加简便,自动关闭在try块中打开的流和其他可关闭的资源。 4. **...

    parallelSorts

    并行排序有多种实现方式,如分而治之的归并排序、快速排序的变种、基于比较的排序和非比较的排序算法等。 在Java中,`java.util.concurrent`包提供了并行排序的相关工具,特别是`Arrays.sort()`方法的并行版本`...

    13、线程池ForkJoinPool实战及其工作原理分析(1).pdf

    - **特点**: 它主要通过`Fork-Join`框架实现,能够有效地管理并行任务,特别是适用于那些可以被细分为更小任务的任务类型。 #### 1.2 ForkJoinPool的工作原理 - **任务的分割与合并**: 在`ForkJoinPool`中,任务...

    JAVA数据结构和算法

    在Java中,我们还可以使用数据流和并行计算框架,如Java 8引入的Stream API和Fork/Join框架,它们为处理大量数据提供了高效和简洁的编程模型。 总的来说,"JAVA数据结构和算法"这个资源将帮助你深入理解如何在Java...

    java的大数据读写

    Java提供了`Arrays.sort()`和`Collections.sort()`方法,但对于大数据,我们可能需要使用更高效的外部排序算法,如归并排序或快速排序的变体。 7. **并发和多线程**:为了加快大数据处理速度,Java的并发和多线程...

    os multithread sorting

    3. **分治策略**:多线程排序常采用分治算法,如快速排序或归并排序。主线程将大任务分解为多个小任务,然后分配给子线程进行排序。子线程完成后再由主线程合并结果。 4. **负载均衡**:为了最大化效率,线程间的...

    java1.7 特性实现

    2. **多路归并排序 (Fork/Join Framework)** Java 7引入了`ForkJoinPool`和`RecursiveAction`,这是一种基于分治策略的并行计算框架。它允许将大任务分解为小任务,然后并行处理这些小任务。例如,实现一个并行归并...

    Sorting

    - Java并发库提供了一种叫做Fork/Join框架的工具,可以用于实现并行排序,如ParallelSort。 总的来说,Java为排序提供了丰富的工具和方法,开发者可以根据具体需求选择合适的方式。理解各种排序算法的工作原理和...

    common.search

    7. **并发搜索**:在多线程环境下,可以使用并发集合(如ConcurrentHashMap)或通过Fork/Join框架并行执行搜索任务。 8. **缓存策略**:使用LRU(Least Recently Used)或LFU(Least Frequently Used)等缓存淘汰...

    卢本捷期末重点口述记录(张艺华记录)1

    在并行排序方面,当数的个数超过处理器个数时,可以采用并行冒泡排序或并行归并排序。如果处理器数量不足,复杂度可能会增加。负载均衡是并行计算中的关键问题,包括集中式和分布式两种策略。集中式负载均衡可能导致...

    c语言做的一个任务管理器源码.zip

    8. **排序算法**:根据需求,可能需要对进程按照CPU使用率、内存占用等指标进行排序,这就涉及到快速排序、归并排序等算法的应用。 9. **文件I/O**:保存和读取任务历史记录或配置文件时,会用到`fopen`、`fprintf`...

    快速查找上万条数据的列子,用于不分页情况

    例如,Python的`multiprocessing`库或Java的`Fork/Join`框架可以实现这一点。 7. **数据压缩**:对大数据进行压缩可以减少存储空间,同时在传输和解压缩过程中也可能节省时间。例如,Gzip或LZ4等压缩算法可以用于这...

    java jdk demo

    4. **Java 7 (Java SE 7)**: 这是Java的一个重要版本,引入了许多新特性,如改进的类型推断(Type Inference with钻石操作符),多路归并排序(Fork/Join Framework),字符串内联优化等。 5. **Windows i586**: ...

Global site tag (gtag.js) - Google Analytics