Fork/Join(2):归并排序

来源:互联网 发布:sql server2005标准版 编辑:程序博客网 时间:2024/04/29 20:22

JDK:1.8.0_20

OS :Win7_64

CPU:双核2.93GHz


  fork/join框架是分治法的体现,因此特别适合归并排序这种分治算法。

  单线程测试排序2亿个整数约59349毫秒使用fork/join测试排序约34635毫秒。可以看到,fork/join框架充分运用了CPU的计算能力,执行时间缩短了近一半。


public class ForkJoinMergeSort {

  public static void main(String[]args)throws InterruptedException, ExecutionException {

    int length = 200000000;

    int[]array =new int[length];

    //随机产生整数

    Randomrandom =new Random();

    for(int i = 0; i <length;i++){

      int x =random.nextInt(1000000000);

      array[i] = x;

    }

    long start = System.currentTimeMillis();

    int[]tmp =new int[length];

    MergeSorttask =new MergeSort(array,tmp, 0,length-1);

    //fork/join框架测试(用时:34635毫秒)

    ForkJoinPoolpool =new ForkJoinPool();

    pool.execute(task);

    while (!task.isDone()){

      Thread.sleep(50);

    }

    pool.shutdown();

    if (task.isCompletedNormally()) {

      System.out.println("UsedTime: " + (System.currentTimeMillis() -start));

    }

    //单线程测试(用时:59349毫秒)

    /*task.sort(array, tmp, 0, length-1);

    System.out.println("UsedTime: " + (System.currentTimeMillis() - start));*/

     

    for (int i = 0; i < 500;i++) {

      System.out.println(array[i]);

    }

  }

}


class MergeSortextends RecursiveAction {

  private static final long serialVersionUID = 3076674975132715659L;

  private final int[]array;

  private final int[]tmp;

  private int first;

  private int last;

  public MergeSort(int[]array,int[]tmp,int first,int last) {

    this.array =array;

    this.tmp =tmp;

    this.first =first;

    this.last =last;

  }

  @Override

  protected void compute() {

    //1. 当排序项分解成少于10000时直接执行归并排序算法

    if (last -first < 10000) {

      sort(array,tmp,first,last);

    }else {

    //2. 当排序项大于10000时,将数组分成两部分(由框架根据条件自动递归分解,直到项数少于10000为止)

      int middle = (first +last) / 2;

      MergeSortt1 =new MergeSort(array,tmp,first,middle);

      MergeSortt2 =new MergeSort(array,tmp,middle + 1,last);

      invokeAll(t1,t2);

      //3. 递归归并排序被分解的两组数字

      merge(array,tmp,first,middle+1,last);

    }

  }

  /** 归并排序 */

  public void sort(int[]array,int[]tmp,int first,int last){

    if(first <last){

      int middle = (first +last)/2;

      sort(array,tmp,first,middle);

      sort(array,tmp,middle+1,last);

      merge(array,tmp,first,middle+1,last);

    }

  }

  /** 归并 */

  private void merge(int[]array,int[]tmp,int leftStart,int rightStart,int rightEnd) {

    int leftEnd =rightStart - 1;

    int tmpPos =leftStart;

    int total =rightEnd -leftStart + 1;

    while(leftStart <=leftEnd &&rightStart <=rightEnd){

      if(array[leftStart ] <=array[rightStart ]){

        tmp[tmpPos++ ] =array[leftStart++ ];

      }else{

        tmp[tmpPos++ ] =array[rightStart++ ];

      }

    }

    while(leftStart <=leftEnd){

      tmp[tmpPos++ ] =array[leftStart++ ];

    }

    while(rightStart <=rightEnd){

      tmp[tmpPos++ ] =array[rightStart++ ];

    }

    for(int i = 0; i <total;i++,rightEnd-- ){

      array[rightEnd ] =tmp[rightEnd ];

    }

  }

}

0 0
原创粉丝点击