今天整理电脑时,看到了多年前写的排序demo,仅仅是demo,真正项目是用不上的。所以花了点时间,该了一下变成可实用的排序工具类(含测试代码),直接贴代码如下了:
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Comparator;
import java.util.List;
import java.util.Random;
import com.freeager.sort.Sort.SortEnum.Order;
/**
* 排序(快速、归并、冒泡)
* @author huangkui<freeager@163.com>
*
*/
public class Sort {
/**
* comparable列表排序
* @param list
* @param sortEnum 排序方法及方式
* @return
*/
public static <T extends Comparable<T>> List<T> sort(List<T> list,SortEnum sortEnum){
return sort(list, Comparator.comparing(t->t),sortEnum);
}
/**
* 列表排序(指定comparator)
* @param list
* @param comparator
* @param sortEnum 排序方法及方式
* @return
*/
@SuppressWarnings("unchecked")
public static <T> List<T> sort(List<T> list,Comparator<T> comparator,SortEnum sortEnum){
if(list ==null || list.size()<=1) {
return list;
}
Object[] array = list.toArray();
sort_(sortEnum, array, (Comparator<Object>)comparator);
List<T> rt = new ArrayList<>();
for(int i=0;i<array.length;i++) {
rt.add((T)array[i]);
array[i] = null;
}
return rt;
}
/**
* comparable数组排序
* @param array
* @param sortEnum 排序方法及方式
*/
public static <T extends Comparable<T>> void sort(T[] array,SortEnum sortEnum) {
sort(array, Comparator.comparing(t->t),sortEnum);
}
/**
* 数组排序(指定comparator)
* @param array
* @param comparator
* @param sortEnum 排序方法及方式
*/
@SuppressWarnings("unchecked")
public static <T> void sort(T[] array,Comparator<T> comparator,SortEnum sortEnum) {
if(array==null || array.length==1) {
return;
}
sort_(sortEnum, array, (Comparator<Object>)comparator);
}
public static enum SortEnum{
QuickAsc("快速排序",Order.Asc),QuickDesc("快速排序",Order.Desc),
MergerAsc("归并排序",Order.Asc),MergerDesc("归并排序",Order.Desc),
BubblingAsc("冒泡排序",Order.Asc),BubblingDesc("冒泡排序",Order.Desc);
private String name;
private Order order;
private SortEnum(String name,Order order){
this.name = name;
this.order = order;
}
@Override
public String toString() {
return name+order.name;
}
public static enum Order{
Asc("升序"),Desc("降序");
private String name;
private Order(String name){
this.name = name;
}
}
}
private static void sort_(SortEnum sortEnum,Object[] array,Comparator<Object> comparator) {
switch (sortEnum) {
case QuickAsc:
case QuickDesc:
quickSort(array, 0, array.length-1, (Comparator<Object>)comparator,sortEnum.order);
break;
case MergerAsc:
case MergerDesc:
Object[] rt = mergerSort((Comparator<Object>)comparator,array, sortEnum.order);
System.arraycopy(rt, 0, array, 0, rt.length);
Arrays.fill(rt, null);
break;
case BubblingAsc:
case BubblingDesc:
bubblingSort(array, (Comparator<Object>)comparator,sortEnum.order);
break;
default:
break;
}
}
/**
* 归并排序
* @param comparator
* @param array
* @param order
* @return
*/
private static Object[] mergerSort(Comparator<Object> comparator,Object[] array,final Order order) {
if(array.length==0) {
return new Object[0];
}
if(array.length==1) {
return new Object[] {array[0]};
}
int m = array.length/2;
//归并排序左半部分
Object[] left = mergerSort(comparator,subArray(array,0,m),order);
//归并排序右半部分
Object[] right = mergerSort(comparator,subArray(array,m,array.length),order);
//以下合并两部分使之有顺序
List<Object> list = new ArrayList<>();
int i=0,j=0,lc=left.length,rc=right.length;
do {
while(i<lc && compare(left[i], right[j], comparator, order) <=0) {
list.add(left[i]);
left[i++] = null;
}
if(i==lc) break;
while(j<rc && compare(right[j], left[i], comparator, order) <=0) {
list.add(right[j]);
right[j++] = null;
}
}while(j<rc);
if(i==lc) {
for(;j<rc;j++) {
list.add(right[j]);
right[j] = null;
}
}
if(j==rc) {
for(;i<lc;i++) {
list.add(left[i]);
left[i] = null;
}
}
return list.toArray();
}
/**
* 截取子数组
* @param array
* @param begin
* @param end
* @return
*/
private static Object[] subArray(Object[] array, int begin, int end) {
Object[] objects = new Object[end-begin];
for(int j=begin;j<end;j++) {
objects[j-begin] = array[j];
}
return objects;
}
/**
* 冒泡排序
* @param array
* @param comparator
* @param order
*/
private static void bubblingSort(Object[] array,Comparator<Object> comparator,final Order order) {
for(int i=array.length-1;i>0;i--) {
boolean swap = false;
for(int j=0;j<i;j++) {
if(compare(array[j], array[j+1], comparator, order)>0) {
Object tmp = array[j+1];
array[j+1] = array[j];
array[j] = tmp;
swap = true;
}
}
if(!swap) {
break;
}
}
}
/**
* 快速排序
*
* @param array
* @param left
* @param right
* @param order
*/
private static void quickSort(Object[] array, int left, int right,Comparator<Object> comparator,final Order order) {
Object middle;
int i, j;
i = left;
j = right;
middle = array[(i + j) / 2];
do {
while (compare(array[i], middle,comparator,order) < 0 && i < right)
i++; // 找出左边比中间值大的数
while (compare(array[j], middle, comparator, order) > 0 && j > left)
j--; // 找出右边比中间值小的数
if (i <= j) { // 将左边大的数和右边小的数进行交换
Object tempDate = array[i];
array[i] = array[j];
array[j] = tempDate;
i++;
j--;
}
} while (i <= j); // 当两者交错时停止
// System.out.println(middle+" "+i+" "+j+" "+Arrays.toString(strDate));
if (i < right) {
quickSort(array, i, right,comparator,order);
}
if (j > left) {
quickSort(array, left, j,comparator,order);
}
}
private static int compare(Object o1, Object o2,Comparator<Object> comparator, Order order) {
switch (order) {
case Asc:
return comparator.compare(o1, o2);
case Desc:
return comparator.compare(o2, o1);
default:
break;
}
return 0;
}
/**
* * @param args
*/
public static void main(String[] args) throws Exception{
test(SortEnum.BubblingAsc);
//上面一次耗时不准确,因为程序刚启动
test(SortEnum.BubblingAsc);
test(SortEnum.BubblingDesc);
test(SortEnum.QuickAsc);
test(SortEnum.QuickDesc);
test(SortEnum.MergerAsc);
test(SortEnum.MergerDesc);
}
private static void test(SortEnum sortEnum) {
long time = System.nanoTime();
List<Integer> oList = Arrays.asList(1,0,3,9,8,4,7);
List<Integer> list = sort(oList,sortEnum);
System.out.println(sortEnum+Arrays.toString(list.toArray()));
list = sort(oList,Comparator.comparing(t->(Integer)t),sortEnum);
System.out.println(sortEnum+Arrays.toString(list.toArray()));
List<Test> testList = new ArrayList<>();
Test t = new Test();
t.i = 1;
t.name = "test";
testList.add(t);
t = new Test();
t.i = 0;
t.name = "test";
testList.add(t);
//
testList = sort(testList,Comparator.comparing(tt->tt.i),sortEnum);
System.out.println(sortEnum+Arrays.toString(testList.toArray()));
List<Test1> test1List = new ArrayList<>();
Test1 tt = new Test1();
tt.i = 1;
tt.name = "test";
test1List.add(tt);
tt = new Test1();
tt.i = 0;
tt.name = "test";
test1List.add(tt);
//
test1List = sort(test1List,sortEnum);
System.out.println(sortEnum+Arrays.toString(test1List.toArray()));
Integer[] integers = new Integer[] {3,2,0,9,8,6,3};
//
sort(integers,sortEnum);
System.out.println(sortEnum+Arrays.toString(integers));
integers = new Integer[] {3,2,0,9,8,6,3};
//
sort(integers,Comparator.comparing(ii->ii),sortEnum);
System.out.println(sortEnum+Arrays.toString(integers));
Test1[] test1Array = new Test1[101];
Test[] testArray = new Test[101];
Random random = new Random();
for(int i=0;i<101;i++) {
test1Array[i] = new Test1();
test1Array[i].i = random.nextInt();
test1Array[i].name = "test";
testArray[i] = new Test();
testArray[i].i = random.nextInt();
testArray[i].name = "test";
}
//
sort(test1Array,sortEnum);
System.out.println(sortEnum+Arrays.toString(test1Array));
//
sort(testArray, Comparator.comparing(ti->ti.i),sortEnum);
System.out.println(sortEnum+Arrays.toString(testArray));
System.out.println(sortEnum+"共耗时:"+(System.nanoTime()-time));
System.out.println("#############################");
}
static class Test1 implements Comparable<Test1>{
Integer i;
String name;
public String toString() {
return name+i;
}
@Override
public int compareTo(Test1 o) {
return this.i.compareTo(o.i);
}
}
static class Test{
Integer i;
String name;
public String toString() {
return name+i;
}
}
}
最后贴出我的电脑上的输出:
冒泡排序升序[0, 1, 3, 4, 7, 8, 9]
冒泡排序升序[0, 1, 3, 4, 7, 8, 9]
冒泡排序升序[test0, test1]
冒泡排序升序[test0, test1]
冒泡排序升序[0, 2, 3, 3, 6, 8, 9]
冒泡排序升序[0, 2, 3, 3, 6, 8, 9]
冒泡排序升序[test-2048479463, test-2038360213, ...省略..., test2094800468, test2114079554]
冒泡排序升序[test-2144890044, test-2040183494, ...省略..., test2041525849, test2096374527]
冒泡排序升序共耗时:83756381
#############################
冒泡排序升序[0, 1, 3, 4, 7, 8, 9]
冒泡排序升序[0, 1, 3, 4, 7, 8, 9]
冒泡排序升序[test0, test1]
冒泡排序升序[test0, test1]
冒泡排序升序[0, 2, 3, 3, 6, 8, 9]
冒泡排序升序[0, 2, 3, 3, 6, 8, 9]
冒泡排序升序[test-2080414993, test-2064199331,...省略..., test2077344746, test2086260643]
冒泡排序升序[test-2120811846, test-2059476038,...省略..., test2044582043, test2128540065]
冒泡排序升序共耗时:6545020
#############################
冒泡排序降序[9, 8, 7, 4, 3, 1, 0]
冒泡排序降序[9, 8, 7, 4, 3, 1, 0]
冒泡排序降序[test1, test0]
冒泡排序降序[test1, test0]
冒泡排序降序[9, 8, 6, 3, 3, 2, 0]
冒泡排序降序[9, 8, 6, 3, 3, 2, 0]
冒泡排序降序[test2061062780, test2018565692, ...省略..., test-2084467908, test-2144923530]
冒泡排序降序[test1989271988, test1959739725, ...省略..., test-2104809398, test-2146464904]
冒泡排序降序共耗时:4608157
#############################
快速排序升序[0, 1, 3, 4, 7, 8, 9]
快速排序升序[0, 1, 3, 4, 7, 8, 9]
快速排序升序[test0, test1]
快速排序升序[test0, test1]
快速排序升序[0, 2, 3, 3, 6, 8, 9]
快速排序升序[0, 2, 3, 3, 6, 8, 9]
快速排序升序[test-2106444367, test-2098220900, ...省略..., test2125293177, test2141803757]
快速排序升序[test-2133479653, test-2105779465, ...省略..., test2085171251, test2107309847]
快速排序升序共耗时:2994379
#############################
快速排序降序[9, 8, 7, 4, 3, 1, 0]
快速排序降序[9, 8, 7, 4, 3, 1, 0]
快速排序降序[test1, test0]
快速排序降序[test1, test0]
快速排序降序[9, 8, 6, 3, 3, 2, 0]
快速排序降序[9, 8, 6, 3, 3, 2, 0]
快速排序降序[test2139869705, test2081018710, ...省略..., test-2042274885, test-2131134815]
快速排序降序[test2142263503, test2134607121, ...省略..., test-2069525773, test-2076766238]
快速排序降序共耗时:2220536
#############################
归并排序升序[0, 1, 3, 4, 7, 8, 9]
归并排序升序[0, 1, 3, 4, 7, 8, 9]
归并排序升序[test0, test1]
归并排序升序[test0, test1]
归并排序升序[0, 2, 3, 3, 6, 8, 9]
归并排序升序[0, 2, 3, 3, 6, 8, 9]
归并排序升序[test-2111459055, test-2048875985, ...省略..., test2115164172, test2116930504]
归并排序升序[test-2145292854, test-2082850971, ...省略..., test2104199685]
归并排序升序共耗时:6164872
#############################
归并排序降序[9, 8, 7, 4, 3, 1, 0]
归并排序降序[9, 8, 7, 4, 3, 1, 0]
归并排序降序[test1, test0]
归并排序降序[test1, test0]
归并排序降序[9, 8, 6, 3, 3, 2, 0]
归并排序降序[9, 8, 6, 3, 3, 2, 0]
归并排序降序[test2114745815, test2073761611, ...省略..., test-2119850832, test-2132757671]
归并排序降序[test2134108493, test2090610124, test1875048353, ...省略..., test-2113591490]
归并排序降序共耗时:1002916
#############################