Fork/Join(2):归并排序

5 篇文章 0 订阅
3 篇文章 0 订阅

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
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值