Bootstrap

【Java高并发学习】奇偶交换排序和希尔排序

奇偶交换排序和希尔排序

1.冒泡排序(串行)

/**
 * 冒泡排序
 * @author wsz
 * @date 2018年1月4日
 */
public class BubbleSort {

	public static void bubbleSort(int[] arr) {
		for(int i = arr.length -1; i > 0; i--) {
			for(int j = 0 ;j < i; j++) {
				if(arr[j] > arr[j+1]) {	//控制大小于便能调整排序
					int temp = arr[j];
					arr[j]   = arr[j+1];
					arr[j+1] = temp;
				}
			}
		}
	}
	
	public static void main(String[] args) {
		int[] arr = {564,4658,457,41,31,45,74,65,8,1,7,3,9,7,54,45455};
		bubbleSort(arr);
		for (int i : arr) {
			System.out.print(i+" ");
		}
	}
}

2.奇偶交换排序(串行)

import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
/**
 * 奇偶交换排序
 * 奇交换:比较奇数索引以及其相邻的后续元素。
 * 偶交换:比较偶数索引和其相邻的后续元素。
 * 两种交换成对出现,保证比较和交换涉及到数组中的每一个元素。
 * @author wsz
 * @date 2018年1月4日
 */
public class OddEvenSort {

	static int[] arr= {25,48,65,87,123,233,456,666,777,8999,55555};
	
	static ExecutorService pool = Executors.newCachedThreadPool();
	
	static int exchFlag = 1;	//记录当前迭代是否发生了数据交换

	public static synchronized int getExchFlag() {
		return exchFlag;
	}

	public static synchronized void setExchFlag(int exchFlag) {
		OddEvenSort.exchFlag = exchFlag;
	}
	
	public static void pOddEvenSort(int[] arr) throws InterruptedException {
		int start = 0;			//记录交换类型。0为偶交换,1为奇交换
		
		//如果上次比较发生了数据交换,或者当前正在进行奇交换,循环不会停止;
		//直到程序不再发生交换,或者当前进行的是偶交换,即奇偶交换已经成对出现。
		while(getExchFlag() == 1 || start ==1) {
			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 OddEvenSortTask(i,latch));
			}
			latch.await();//等待所有线程结束
			start = start ==0 ? 1 : 0;
		}
	}
	
	static class OddEvenSortTask implements Runnable{
		int i;
		CountDownLatch latch;
		
		public OddEvenSortTask(int i, CountDownLatch latch) {
			super();
			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;
				setExchFlag(1); //数据进行了交换
			}
			latch.countDown();//结束当前线程的任务,倒计时器-1
		}
	}
	
	public static void main(String[] args) throws InterruptedException {
		pOddEvenSort(arr);
		for (int i : arr) {
			System.out.print(i+" ");
		}
	}
}

3.希尔排序

/**
 * 希尔排序
 * @author wsz
 * @date 2018年1月4日
 */
public class ShellSort {
	/*
	 * 1.将n个元素的数组分成n/2个数字序列,第1个数据和第n/2+1个数据为一对...
	 * 2.一次循环使每一个序列对排好顺序
	 * 3.然后,再变为n/4个序列,再次排序。
	 * 4.重复上述过程,直到序列减为1个,结束
	 * @param arr
	 */
	public static void sort(int[] arr) {
		for(int r = arr.length/2; r >= 1; r/=2) {//分成2组,
			for(int i = r; i<arr.length; i++) {
				int temp = arr[i];
				int j    = i-r;
				
				while(j >= 0 && temp < arr[j]) {
					arr[j+r] = arr[j];
					j -= r;
				}
				
				arr[j+r] = temp;
			}
		}
	}
	
	/**
	 * @param arr
	 */
	public static void sort1(int[] arr) {
		int h = 1;
		while(h <= arr.length/2) {
			h = h*2+1;
		}
		while(h > 0) {
			for(int i = h; i< arr.length; i++) {
				if(arr[i] < arr[i-h]) {
					int temp = arr[i];
					int j    = i - h;
					while(j >= 0 && arr[j] > temp) {
						arr[j + h] = arr[j];
						j -= h;
					}
					arr[j+h] = temp;
				}
			}
			h = (h-1)/2;
		}
	}
	
	public static void main(String[] args) {
		int[] arr = {564,4658,457,41,31,45,74,65,8,1,7,3,9,7,54,45455};
		sort(arr);
//		sort1(arr);
		for (int i : arr) {
			System.out.print(i+" ");
		}
	}
}

4.希尔排序(串行)

import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
/**
 * 并行情况下的希尔排序
 * @author wsz
 * @date 2018年1月4日
 */
public class ShellSortS {

	static int[] arr= {25,48,65,87,123,233,456,666,777,8999,55555};
	
	static ExecutorService pool = Executors.newCachedThreadPool();
	
	static class ShellSortTask implements Runnable{

		int i = 0;
		int h = 0;
		CountDownLatch latch;
		
		public ShellSortTask(int i, int h, CountDownLatch latch) {
			super();
			this.i = i;
			this.h = h;
			this.latch = latch;
		}

		@Override
		public void run() {
			if(arr[i] < arr[i-h]) {
				int temp = arr[i];
				int j    = i - h;
				while(j >= 0 && arr[j] > temp) {
					arr[j+h] = arr[j];
					j -= h;
				}
				arr[j+h] = temp;
			}
			latch.countDown();
		}
		
	}
	
	public static void pShellSort(int[] arr) throws InterruptedException {
		int h = 1;
		CountDownLatch latch = null;
		while( h <= arr.length/3) {
			h = h*3+1;
		}
		while(h > 0) {
			if(h >= 4) 
				latch = new CountDownLatch(arr.length - h);
			for(int i = h; i < arr.length; i++) {
				if(h >= 4) {
					pool.execute(new ShellSortTask(i, h, latch));
				}else {
					if(arr[i] < arr[i-h]) {
						int temp = arr[i];
						int j = i -h;
						while(j >= 0 && arr[j] > temp) {
							arr[j+h] = arr[j];
							j -= h;
						}
						arr[j+h] = temp;
					}
				}
			}
			latch.await();
			h = (h-1) / 3;
		}
	}
	
	public static void main(String[] args) throws InterruptedException {
		pShellSort(arr);
		for (int  i : arr) {
			System.out.print(i+" ");
		}
	}

}



悦读

道可道,非常道;名可名,非常名。 无名,天地之始,有名,万物之母。 故常无欲,以观其妙,常有欲,以观其徼。 此两者,同出而异名,同谓之玄,玄之又玄,众妙之门。

;