比如对于一个序列 A [3,5,7,9,10,17,19,22,17,15,12,10,9,8,5,1],明显看出它是一个双调序列,其中X为[3,5,7,9,10,17,19,22]单调递增,Y为[17,15,12,10,9,8,5,1]单调递减,且X序列长度等于Y序列长度,我们试着按照上面定理将数据按照原序进行比较,得到MAX和MIN两个序列,它们分别为 MAX [17,15,12,10,10,17,19,22],MIN [3,5,7,9,9,8,5,1],对MAX和MIN按照Batcher定理继续拆分……
privatestaticvoidsort(int[] a, int lo, int n, boolean dir){ if (n > 1) { int m = n / 2; sort(a, lo, m, ASCENDING); sort(a, lo + m, m, DESCENDING); bitonicMerge(a, lo, n, dir); } }
privatestaticvoidbitonicMerge(int[] a, int lo, int n, boolean dir){ if (n > 1) { int m = n / 2; for (int i = lo; i < lo + m; i++) { compare(a, i, i + m, dir); } bitonicMerge(a, lo, m, dir); bitonicMerge(a, lo + m, m, dir); } }
privatestaticvoidcompare(int[] a, int i, int j, boolean dir){ if (dir == (a[i] > a[j])) { exchange(a, i, j); } }
privatestaticvoidexchange(int[] a, int i, int j){ int t = a[i]; a[i] = a[j]; a[j] = t; }
publicstaticvoidmain(String[] args){ int[] a = newint[128]; Random r = new Random(); for (int i = 0; i < a.length; i++) { a[i] = r.nextInt(10000); } System.out.println("BitonicSort排序前:"); System.out.println(Arrays.toString(a)); bitonicSort(a); System.out.println("BitonicSort排序后:"); System.out.println(Arrays.toString(a)); } }
privatestaticvoidsort(int[] a, int lo, int n, boolean dir){ if (n > 1) { int m = n / 2; sort(a,lo, m, !dir); sort(a,lo + m, n - m, dir); bitonicMerge(a,lo, n, dir); } }
privatestaticvoidbitonicMerge(int[] a,int lo, int n, boolean dir){ if (n > 1) { int m = greatestPowerOfTwoLessThan(n); for (int i = lo; i < lo + n - m; i++) { compare(a,i, i + m, dir); } bitonicMerge(a,lo, m, dir); bitonicMerge(a,lo + m, n - m, dir); } }
privatestaticvoidcompare(int[] a,int i, int j, boolean dir){ if (dir == (a[i] > a[j])) { exchange(a,i, j); } }
privatestaticvoidexchange(int[] a,int i, int j){ int t = a[i]; a[i] = a[j]; a[j] = t; }
privatestaticintgreatestPowerOfTwoLessThan(int n){ int k = 1; while (k < n) { k = k << 1; } return k >> 1; }
publicstaticvoidmain(String[] args){ int[] a = newint[9]; Random r = new Random(); for (int i = 0; i < a.length; i++) { a[i] = r.nextInt(10000); } System.out.println("BitonicSort排序前:"); System.out.println(Arrays.toString(a)); bitonicSort(a); System.out.println("BitonicSort排序后:"); System.out.println(Arrays.toString(a));
privatestaticvoidsort(int[] a, int lo, int n, boolean dir){ if (n > 1) { int m = n / 2; if(n > PIECE){ Future future1 = parallelSort(a, lo, m, !dir); Future future2 = parallelSort(a, lo + m, n - m, dir); while (true){ if(future1.isDone()&&future2.isDone()){ break; } } }else{ sort(a, lo, m, !dir); sort(a, lo + m, n - m, dir); } bitonicMerge(a, lo, n, dir); } }
privatestaticvoidbitonicMerge(int[] a, int lo, int n, boolean dir){ if (n > 1) { int m = greatestPowerOfTwoLessThan(n); for (int i = lo; i < lo + n - m; i++) { compare(a, i, i + m, dir); } if(n > PIECE){ Future future1 = parallelMerge(a, lo, m, dir); Future future2 = parallelMerge(a, lo + m, n - m, dir); while (true){ if(future1.isDone()&&future2.isDone()){ break; } } }else{ bitonicMerge(a, lo, m, dir); bitonicMerge(a, lo + m, n - m, dir); } } }
privatestaticvoidcompare(int[] a, int i, int j, boolean dir){ if (dir == (a[i] > a[j])) { exchange(a, i, j); } }
privatestaticvoidexchange(int[] a, int i, int j){ int t = a[i]; a[i] = a[j]; a[j] = t; }
privatestaticintgreatestPowerOfTwoLessThan(int n){ int k = 1; while (k < n) { k = k << 1; } return k >> 1; }
privatestatic Future parallelSort(int[] a, int lo, int n, boolean dir){ return executorService.submit(()->sort(a,lo,n,dir)); }
privatestatic Future parallelMerge(int[] a, int lo, int n, boolean dir){ return executorService.submit(()->bitonicMerge(a,lo,n,dir)); }
publicstaticvoidmain(String[] args){ int[] a = newint[100000000]; Random r = new Random(); for (int i = 0; i < a.length; i++) { a[i] = r.nextInt(100000000); } System.out.println("BitonicParallelSort排序开始:"); long start = System.currentTimeMillis(); bitonicSort(a); System.out.println("BitonicParallelSort耗时:"+(System.currentTimeMillis()-start)+"ms"); System.out.println("BitonicParallelSort排序完成!"); System.out.println("数组是否有序:"+isOrdered(a)); }
privatestaticvoidsort(int[] a, int lo, int n, boolean dir){ if (n > 1) { int m = n / 2; if(n > PIECE){ Future future1 = parallelSort(a, lo, m, !dir); Future future2 = parallelSort(a, lo + m, n - m, dir); while (true){ if(future1.isDone()&&future2.isDone()){ break; } } }else{ Future future1 = parallelQuickSort(a, lo, lo + m - 1, !dir); Future future2 = parallelQuickSort(a, lo + m, lo + n - 1, dir); while (true){ if(future1.isDone()&&future2.isDone()){ break; } } } bitonicMerge(a, lo, n, dir); } }
privatestaticvoidbitonicMerge(int[] a, int lo, int n, boolean dir){ if (n > 1) { int m = greatestPowerOfTwoLessThan(n); for (int i = lo; i < lo + n - m; i++) { compare(a, i, i + m, dir); } if(n > PIECE){ Future future1 = parallelMerge(a, lo, m, dir); Future future2 = parallelMerge(a, lo + m, n - m, dir); while (true){ if(future1.isDone()&&future2.isDone()){ break; } } }else{ bitonicMerge(a, lo, m, dir); bitonicMerge(a, lo + m, n - m, dir); } } }
privatestaticvoidcompare(int[] a, int i, int j, boolean dir){ if (dir == (a[i] > a[j])) { exchange(a, i, j); } }
privatestaticvoidexchange(int[] a, int i, int j){ int t = a[i]; a[i] = a[j]; a[j] = t; }
privatestaticintgreatestPowerOfTwoLessThan(int n){ int k = 1; while (k < n) { k = k << 1; } return k >> 1; }
privatestatic Future parallelSort(int[] a, int lo, int n, boolean dir){ return executorService.submit(()->sort(a,lo,n,dir)); }
privatestatic Future parallelMerge(int[] a, int lo, int n, boolean dir){ return executorService.submit(()->bitonicMerge(a,lo,n,dir)); }