美文网首页
归并排序的多线程版本

归并排序的多线程版本

作者: spslcs | 来源:发表于2015-04-30 15:25 被阅读0次

最近在学习java多线程,读了《java多线程编程实战》有一种所有的串行操作都可以写成并发的错觉,所以决定练练手,因为递归操作最适合并发操作(除了io等)所以写了一个并发版本的归并排序,并顺手撸了个串行的归并排序,没想到在<1000000的数量级中竟然比系统提供的排序要快。show you the code

  • 首先是生成随机数组(比较乱,也没有优化,不是重点)
class SuijiArray {
    private int length = 0;
    private int index = 0;
    private int[] array = null;
    Random rand = new Random();
    SuijiArray(int le) {
        length = le;
        index = le-1;
        array = new int[length];
        for(int i = 0; i < length; i++) {
            array[i] = i+1;
        }
    }
    
    public int[] get() {
        int[] a = new int[length];
        
        for(int i = 0; i< length; i++) {
            a[i] = next();
        }
        
        return a;
    }
    
    private int next() {
        if(index == 0){
            return array[0];
        }
        int random = rand.nextInt(index);
        int result = array[random];
        swap(array,index--,random);
        return result;
    }
    private void swap(int[] a, int i, int j) {
        int t = a[i];
        a[i] = a[j];
        a[j] = t;
    }
}```

- 然后是一般的归并排序

   public static void insertSort(int[] a,int start, int end) {
    for(int i = start + 1; i < end; i++) {
        int t = a[i];
        int j = i;
        for(; j > start && t < a[j-1]; j--) {
            a[j] = a[j-1];
        }
        a[j] = t;
    }
}


public static void mergeSort(int[] a, int start, int end){
    //在数组笔记小的时候,切换到插入排序,提供性能
    if((end - start) <= INSERT_SORT_LENGTH ) {
        insertSort(a, start, end);
    } else {
        int mid = (start + end) /2;
        mergeSort(a,start,mid);
        mergeSort(a, mid, end);
        merge(a, start, mid, end);
    }
}

public static void merge(int[] a, int start, int mid, int end) {
    int[] b= new int[end-start];
    
    int k = 0;
    int i = start ;
    int j = mid;
    
    while(i < mid && j < end) {
        if(a[i] < a[j]) {
            b[k++] = a[i++];
        }else {
            b[k++] = a[j++];
        }
    }
    
    if(i == mid) {
        while(j < end) {
            b[k++] = a[j++];
        }
    }else {
        while(i < mid) {
            b[k++] = a[i++];
        }
    }
    
    for(int ii = 0; ii < (end - start);ii++) {
        a[start + ii] = b[ii];
    }
    
}```
  • 多线程
public class ForkAndJoinTest extends RecursiveTask{
    public static final int INSERT_SORT_LENGTH = 23;
    private static final long serialVersionUID = 1L;
    private int[] array = null;
    private int start;
    private int end;
    
    ForkAndJoinTest(int[] a, int s, int e) {
        array = a;
        start = s;
        end = e;
    }
    

    protected Object compute() {
        boolean canCompute = (end - start) <= INSERT_SORT_LENGTH;
        if(canCompute){
            insertSort(array, start, end);
        }else{
            
            int mid = (end + start)/2;
            ForkAndJoinTest left = new ForkAndJoinTest(array,start,mid);
            ForkAndJoinTest right = new ForkAndJoinTest(array,mid,end);
            
            left.fork();
            right.fork();
            
            left.join();
            right.join();
            
            merge(array,start,mid,end);
        }
        
        return null;
    }
}
  • 测试数据
public static int[] deepCopy(int[] a) {
        int b[] = new int[a.length];
        for(int i = 0; i <  a.length; i++) {
            b[i] = a[i];
        }
        return b;
    }
    
    public static void main(String[] args) {

        ForkJoinPool forkJoinPool =new ForkJoinPool(6);
        
        int[] array = new SuijiArray(50000).get();
        int[] barray = deepCopy(array);
        int[] carray = deepCopy(array);
        ForkAndJoinTest test = new ForkAndJoinTest(array,0,array.length);
        long end = 0l;
        long start = System.currentTimeMillis();
        Future future = forkJoinPool.submit(test); 
        try {
            future.get();
        end = System.currentTimeMillis();
        } catch (InterruptedException e) {
            e.printStackTrace();
        } catch (ExecutionException e) {
            e.printStackTrace();
        }
        
        System.out.println("concurrentMergeSort:"+(end-start));
        
        long start1 = System.currentTimeMillis();
        mergeSort(barray, 0, barray.length);
        long end1 = System.currentTimeMillis();
        System.out.println("mergeSortTime=:"+(end1 - start1));
        
        long start2 = System.currentTimeMillis();
        Arrays.sort(carray);
        long end2 = System.currentTimeMillis();
        System.out.println("SystemSortTime=:"+(end2 - start2));
        
    }```

相关文章

  • 归并排序的多线程版本

    最近在学习java多线程,读了《java多线程编程实战》有一种所有的串行操作都可以写成并发的错觉,所以决定练练手,...

  • 多线程合并有序集

    在归并排序中,有个合并有序集操作。之前在用多线程实现归并排序中,并没将合并操作多线程化,导致并行度只有log(n)...

  • 多线程归并排序改进版

    利用多线程归并有序集改进了下多线程排序,只剩下多线程拷贝没实现了。。。 代码 benchmark代码 测试结果

  • 排序二:归并、快排

    文章结构 归并排序 快速排序 源码 1. 归并排序 1.1 什么是归并排序 归并排序的思想是:将待排序的区间平分成...

  • 排序算法

    约定 选择排序 冒泡排序 插入排序 希尔排序 归并排序1. 归并方法2. 自顶向下归并排序3. 自底向上归并排序 ...

  • java归并排序

    归并排序什么是归并排序:图解归并排序归并排序有两种实现方式,一是基于递归,而是基于迭代1)基于递归的归并排序: 基...

  • 多线程快速排序

    本文为大家介绍下快速排序算法的多线程写法。 按此逻辑也可以对归并排序进行改造,读者可先自行研究

  • 排序算法之归并排序

    归并排序(Merge Sort) 归并排序是利用归并的思想实现排序的方式,该算法采用的是经典的分治算法 归并排序过...

  • 算法—排序篇2

    1、归并排序(Merging Sort) 归并排序(Merging Sort): 就是利用归并的思想实现排序⽅法....

  • 算法 第二章第二部分笔记

    各种排序算法的性能特点 选择排序 插入排序 希尔排序 归并排序 本地归并排序 自底向上的归并排序 快速排序 三向切...

网友评论

      本文标题:归并排序的多线程版本

      本文链接:https://www.haomeiwen.com/subject/pqqbfttx.html