package suanfa;
import java.util.Random;
/**
*
* <p>Title: SortTest.java</p>
* <p>Description: 冒泡排序,归并排序,快速排序,计数排序</p>
* 各种算法的事件复杂度比较大,同时排序80000个数(0~99之间),
* 冒泡排序:6406ms n*n
* 归并排序:108ms nlgn
* 快速排序:89ms nlgn
* 计数排序:9ms 在数的范围很小时,t(n) = n+k
* 基数排序:18ms 针对较大的数字范围,结合计数排序使用。
* <p>Copyright: Copyright (c) 2013</p>
* <p>Company: szgr</p>
* @author xuhong
* @date 2013-10-31
* @version 1.0
*/
class SortHelp {
private static final int RANDOM_INT = 100;
/**
* 基数排序
* 先排序个位数,再排序十位数,以此类推,每个排序使用
* 计数排序
* @param sortAry sortAry的数都是大于0的
* @return
*/
public static int[] radixSort(int[] sortAry){
int[] ary = copy(sortAry,0,sortAry.length-1);
long begin = System.currentTimeMillis();
int maxValue = ary[0];
//求最大值
for(int i = 0; i < ary.length;i++){
int tempValue = ary[i];
if(maxValue < tempValue){
maxValue = tempValue;
}
}
int bitCount = getBit(maxValue);
for(int i = 1;i <= bitCount;i++){
ary = countHelpSort(ary,i);
}
long end = System.currentTimeMillis();
System.out.println("基数排序,排数组为"+sortAry.length+"的数组所耗费的时间为:"+(end-begin)+"毫秒!");
return ary;
}
private static int getBit(int x){
int y = x;
int result = 1;
while(y >= 10 && y/10 != 0){
y = y/10;
result++;
}
return result;
}
/**
* 获取某个数的某个位数的值
* @param x
* @param bit
* @return
*/
private static int getValue(int x ,int bit){
if(bit == 1){
return x % 10;
}else{
int tempX = x / 10;
return getValue(tempX,bit-1);
}
}
/**
*
* @param sortAry 待排序的数组
* @param bit 按照哪一位进行排序,bit=1为个位,bit=2为十位
* @return
*/
private static int[] countHelpSort(int[] sortAry,int bit){
int[] countAry = new int[10];//0 至 9
for(int i = 0;i < sortAry.length;i++){
int temp = sortAry[i];
int value = getValue(temp,bit);
countAry[value] = countAry[value]+1;
}
int tempValue = countAry[0];
for(int i = 1;i < countAry.length;i++){
if(countAry[i] > 0){
countAry[i] = tempValue+countAry[i];
tempValue = countAry[i];
}
}
int tempIndex = -1;
for(int i =countAry.length-1;i>=0;i--){
if(countAry[i] > 0){
if(tempIndex != -1){
countAry[tempIndex] = countAry[i];
}
tempIndex = i;
}
}
countAry[0] = 0;
int[] result = new int[sortAry.length];
for(int i = 0;i < sortAry.length;i++){
int temp = sortAry[i];
int value = getValue(temp,bit);
int countValue = countAry[value]; //获取位置
result[countValue] = temp;
countAry[value] = countAry[value]+1;
}
return result;
}
/**
* 计数排序算法,适用于sortAry的数组的值范围较小,
* 比如以下为50000个0到99的数
* @param sortAry
*/
public static int[] countSort(int[] sortAry){
return countSort(sortAry,RANDOM_INT);
}
private static int[] countSort(int[] sortAry,int countInt){
long begin = System.currentTimeMillis();
//知道是1至100的数
int[] countAry = new int[countInt];
for(int i = 0;i < sortAry.length;i++){
int temp = sortAry[i];
countAry[temp] = countAry[temp]+1;
}
//算出位置
int tempValue = countAry[0];
for(int i = 1;i < countAry.length;i++){
if(countAry[i] > 0){
countAry[i] = tempValue+countAry[i];
tempValue = countAry[i];
}
}
int[] result = new int[sortAry.length];
for(int i = 0;i < sortAry.length;i++){
int temp = sortAry[i];
int countIndex = countAry[temp]-1;
result[countIndex] = temp;
countAry[temp] = countAry[temp]-1;
}
long end = System.currentTimeMillis();
System.out.println("计数排序,排数组为"+sortAry.length+"的数组所耗费的时间为:"+(end-begin)+"毫秒!");
return result;
}
/**
* 快速排序
* @param sortAry
* @return
*/
public static int[] quickSort(int[] sortAry){
long begin = System.currentTimeMillis();
int[] ary = copy(sortAry, 0, sortAry.length-1);
quickSort(ary,0,sortAry.length-1);
long end = System.currentTimeMillis();
System.out.println("快速排序,排数组为"+sortAry.length+"的数组所耗费的时间为:"+(end-begin)+"毫秒!");
return ary;
}
/**
* 比如两个数组
* start等于0,end等于1
* @param sortAry
* @param start 数组的开始位置
* @param end 数组的结束位置
*/
private static void quickSort(int[] sortAry,int start,int end){
if(start >= end){
return;
}
int temp = sortAry[start];
int j = start+1;
for(int k = start+1;k <= end;k++){
if(sortAry[k] <= temp){
swap(sortAry,j,k);
j++;
}
}
j--;
swap(sortAry,start,j);
quickSort(sortAry,start,j-1);
quickSort(sortAry,j+1,end);
}
/**
* 归并排序
* 算法为t(n) = nlgn;
* @param mergeAry
* @return
*/
public static int[] mergeSort(int[] mergeAry){
long begin = System.currentTimeMillis();
int[] result = mergeSort(mergeAry,0,mergeAry.length-1);
long end = System.currentTimeMillis();
System.out.println("归并排序,排数组为"+mergeAry.length+"的数组所耗费的时间为:"+(end-begin)+"毫秒!");
return result;
}
/**
* 归并排序
* @param mergeAry
* @return
*/
private static int[] mergeSort(int[] mergeAry,int start,int end){
if(end-start < 1){
return copy(mergeAry,start,end);
}else{
int middle = (start+end)/2;
int[] leftSortAry = mergeSort(mergeAry,start,middle);
int[] rightSortAry = mergeSort(mergeAry,middle+1,end);
int[] result = new int[end-start+1];
int left = 0;
int right = 0;
for(int i = 0;i < result.length;i++){
if(left == leftSortAry.length){
result[i] = rightSortAry[right];
right++;
continue;
}
if(right == rightSortAry.length){
result[i] = leftSortAry[left];
left++;
continue;
}
if(leftSortAry[left] < rightSortAry[right]){
result[i] = leftSortAry[left];
left++;
}else{
result[i] = rightSortAry[right];
right++;
}
}
return result;
}
}
/**
* 冒泡排序
* 算法的t(n) = n的平方
* @param ary
* @return
*/
public static int[] bubbleQuery(int[] bubbleAry){
int[] ary = copy(bubbleAry,0,bubbleAry.length-1);
long begin = System.currentTimeMillis();
for(int i = 0;i < ary.length;i++){
for(int j = i+1;j < ary.length;j++){
if(ary[i] > ary[j]){
swap(ary,i,j);
}
}
}
long end = System.currentTimeMillis();
System.out.println("冒泡排序,排数组为"+ary.length+"的数组所耗费的时间为:"+(end-begin)+"毫秒!");
return ary;
}
/**
* 返回一个1到100的10000的数组
* @param length 生成数组的长度
* @return
*/
public static int[] getIntArray(int length) {
int[] result = new int[length];
Random r = new Random();
for (int i = 0; i < length; i++) {
int temp = r.nextInt(RANDOM_INT);
result[i] = temp;
}
return result;
}
/**
*
* @param ary 要打印的数组
*/
public static void print(int[] ary) {
for (int i = 0; i < ary.length; i++) {
System.out.print(ary[i]+" ");
if(i % 30 == 0 && i > 0){
System.out.println();
}
}
System.out.println();
}
/**
* 复制数组
* @param ary
* @return
*/
private static int[] copy(int[] ary,int start,int end){
int[] result = new int[end-start+1];
for(int i = 0;i < result.length;i++,start++){
result[i] = ary[start];
}
return result;
}
/**
* 数组交换
* @param ary
* @param i
* @param j
*/
private static void swap(int[] ary,int i ,int j){
int temp = ary[i];
ary[i] = ary[j];
ary[j] = temp;
}
}
public class SortTest {
public static void main(String[] args) {
int len = 80000;
int[] ary = SortHelp.getIntArray(len);
System.out.println("冒泡排序。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。");
int[] sortAry = SortHelp.bubbleQuery(ary);
System.out.println(sortAry.length);
//SortHelp.print(sortAry);
System.out.println("归并排序。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。");
int[] result = SortHelp.mergeSort(ary);
System.out.println(result.length);
//SortHelp.print(result);
System.out.println("快速排序。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。");
int[] quickAry = SortHelp.quickSort(ary);
System.out.println(quickAry.length);
//SortHelp.print(quickAry);
System.out.println("计数排序。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。");
int[] countAry = SortHelp.countSort(ary);
System.out.println(countAry.length);
//SortHelp.print(countAry);
System.out.println("基数排序。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。");
int[] radixAry = SortHelp.radixSort(ary);
System.out.println(radixAry.length);
}
}