2017-04-18 64 views
1

我想用叉子来实现双调排序连接java.So的模型继承人分拣机java.lang.NoClassDefFoundError同时做双调排序

import java.util.concurrent.RecursiveAction; 

public class BitonicSortTask extends RecursiveAction 
{ 
    private final int array[]; 
    private final int low; 
    private final int high; 
    private final int dir; 

    public BitonicSortTask(int array[],int low,int high,int dir) 
    { 
     this.array = array; 
     this.low = low; 
     this.high = high; 
     this.dir= dir; 
    } 

    @Override 
    protected void compute() 
    { 
     if(high>1) 
     { 
      int temp = high/2; 
      BitonicSortTask left = new BitonicSortTask(array, low, temp,1); 
      BitonicSortTask right = new BitonicSortTask(array, temp+1,high,0); 
      invokeAll(left, right); 
      BitonicMerge(array, low, high, dir); 
     } 
    } 

    private void BitonicMerge(int[] array,int low,int high,int dir) 
    { 
     if(high>1) 
     { 
      int temp = high/2; 
      for (int i=low; i<low+temp; i++) 
       compAndSwap(array,i, i+temp, dir); 
      BitonicMerge(array, low, temp, dir); 
      BitonicMerge(array, temp+1, high, dir); 
     } 
    } 

    private void compAndSwap(int a[],int i,int j,int dir) 
    { 
     if ((a[i] > a[j] && dir == 1)||(a[i] < a[j] && dir == 0)) 
     { 
      int temp = a[i]; 
      a[i] = a[j]; 
      a[j] = temp; 
     } 
    } 
} 

和主(试验班)的代码

import java.util.Arrays; 
import java.util.concurrent.ForkJoinPool; 

public class BitonicSortTest 
{ 
    public static void main(String[] args) 
    { 
     int l=0; 
     int h=999; 
     int a[] = new int[10]; 
     for(int i=0; i<10; i++) 
     { 
      a[i] = (int) (i*Math.round(Math.random())); 
     } 
     BitonicSortTask task = new BitonicSortTask(a, l, h, 1); 
     ForkJoinPool fjp= new ForkJoinPool(); 
     fjp.invoke(task); 
     System.out.println(Arrays.toString(a)); 
    } 
} 

但每当我运行这段代码我得到

Exception in thread "main" java.lang.NoClassDefFoundError: Could not 
initialize class java.util.concurrent.locks.AbstractQueuedSynchronizer$Node 

你能告诉我该怎么原因解决它。

+0

发布完整的堆栈跟踪 – njzk2

+0

当我尝试运行此操作时,出现'StackOverflowError' – James

回答

4

问题是你缩小了导入的范围,因为编译器不会警告你。要正确使用Fork/Join-Framework,您必须使用通配符导入。

你的类BitonicSortTask.java需要

import java.util.*; 
import java.util.concurrent.*; 

而且你的类BitonicSortTest.java需要

import java.util.concurrent.*; 

那么你的程序将正常运行。

+0

通配符导入不需要使用Java Fork/Join。 – James

0

问题是您的排序算法已损坏。这导致StackOverFlowError,并且由于堆栈已用尽,因此通常会将此错误报告为ClassDefNotFoundError

你的试验也具有在它的一个问题声明H = 999时,它应该是数组的大小进行排序(即a.length

在我所提到的以下实施例的算法的固定:

的算法所需要的变化是简单

  1. 当计算temp考虑这个用于排序两侧的新high
  2. 计算temp时,使用此值计算排序前半部分中的新low

下面的类包含这些修补程序:

import java.util.concurrent.RecursiveAction; 

public class BitonicSortTask extends RecursiveAction { 

    private final int array[]; 
    private final int low; 
    private final int high; 
    private final int dir; 

    public BitonicSortTask(int array[], int low, int high, int dir) { 
     this.array = array; 
     this.low = low; 
     this.high = high; 
     this.dir = dir; 
    } 

    @Override 
    protected void compute() { 
     if (high > 1) { 
      int temp = high/2; 
      // from low, with a size of temp 
      BitonicSortTask left = new BitonicSortTask(array, low, temp, 1); 
      // from low + temp, with a size of temp 
      BitonicSortTask right = new BitonicSortTask(array, low + temp, temp, 0); 
      invokeAll(left, right); 
      BitonicMerge(array, low, high, dir); 
     } 
    } 

    private void BitonicMerge(int[] array, int low, int high, int dir) { 
     if (high > 1) { 
      // temp is the mid point, and also the new 'high' for both parts 
      int temp = high/2; 
      for (int i = low; i < low + temp; i++) { 
       compAndSwap(array, i, i + temp, dir); 
      } 
      // from low, with a size of temp 
      BitonicMerge(array, low, temp, dir); 
      // from low + temp, with a size of temp 
      BitonicMerge(array, low + temp, temp, dir); 
     } 
    } 

    private void compAndSwap(int a[], int i, int j, int dir) { 
     if ((a[i] > a[j] && dir == 1) || (a[i] < a[j] && dir == 0)) { 
      int temp = a[i]; 
      a[i] = a[j]; 
      a[j] = temp; 
     } 
    } 
} 

而对于Test类。只需检查数组的大小。

import java.util.Arrays; 
import java.util.concurrent.ForkJoinPool; 

public class BitonicSortTest { 

    public static void main(String[] args) { 
     int a[] = new int[1 << 4]; 
     for (int i = 0; i < a.length; i++) { 
      a[i] = (int) (Math.round(100 * Math.random())); 
     } 
     // Don't need variables for low/hi (it's just zero and array length) 
     BitonicSortTask task = new BitonicSortTask(a, 0, a.length, 1); 
     ForkJoinPool fjp = new ForkJoinPool(); 
     fjp.invoke(task); 
     System.out.println(Arrays.toString(a)); 
    } 
} 

买者

该算法仅适用于阵列具有长度为2的见Bitonic sorting for n not a power of 2的功率。