
奇偶排序解开了冒泡排序每次迭代交换数据的相关性。它将排序分为两个过程,奇交换和偶交换。
对于奇交换来说,它总是比较奇数索引及其相邻的后续元素。
对于偶交换来说,它总是比较偶数索引及其相邻的后续元素。
奇交换和偶交换会成对出现,这样能保证比较和交换涉及数组中的每一个元素。
奇偶交换的串行实现
public static void oddEventSort(int[] arr){
int exchFlag = 1, start = 0;
while(exchFlag == 1 || start == 1){
exchFlag = 0;
for(int i = start; i<arr.length-1; i+=2){
if(arr[i] > arr[i+1]){
int temp = arr[i];
arr[i] = arr[i+1];
arr[i+1] = temp;
exchFlag = 1;
}
}
if(0 == start){
start = 1;
}else{
start = 0;
}
}
}
奇偶交换的并行实现
static int[] arr = {1, 4, 5, 2, 3};
static ExecutorService pool = Executors.newCachedThreadPool();
static int exchFlag = 1;
static synchronized void setExchFlag(int v){
exchFlag = v;
}
static synchronized int getExchFlag(){
return exchFlag;
}
public static class oddEventSortTask implements Runnable {
int i ;
CountDownLatch latch;
public oddEventSortTask(int i, CountDownLatch latch){
this.i = i;
this.latch = latch;
}
@Override
public void run(){
if(arr[i] > arr[i+1]){
int temp = arr[i];
arr[i] = arr[i+1];
arr[i+1] = temp;
exchFlag = 1;
}
latch.countDown();
}
}
public static void pOddEventSort(int[] arr) throws InterruptedException{
int start = 0;
while(1 == getExchFlag() || 1 == start){
setExchFlag(0);
//偶数的数组长度,当start为1时,只有len/2-1个线程
CountDownLatch latch = new CountDownLatch(arr.length/2 - (arr.length%2 == 0?start : 0));
for(int i =start; i<arr.length-1; i +=2){
pool.submit(new oddEventSortTask(i, latch));
}
//等待所有线程结束
latch.await();
if(0 == start){
start = 1;
}else{
start = 0;
}
}
}