/**
* 排序测试
*/
public class SortTest {
/**
* 升序排列
*/
public static final int SORT_TYPE_AEC = 1;
/**
* 降序排列
*/
public static final int SORT_TYPE_DEC = 2;
public static void main(String[] args) {
Map<Long, Integer> testMap1 = new HashMap<Long, Integer>();
Map<Long, Integer> testMap2 = new HashMap<Long, Integer>();
Map<Long, Integer> testMap3 = new HashMap<Long, Integer>();
Map<Long, Integer> testMap4 = new HashMap<Long, Integer>();
Map<Long, Integer> testMap5 = new HashMap<Long, Integer>();
Map<Long, Integer> testMap6 = new HashMap<Long, Integer>();
Random random = new Random(System.currentTimeMillis());
for (Long i = 12345678900000L; i < 12345678905000L; i++) {
int value = random.nextInt(100000);
testMap1.put(i, value);
testMap2.put(i, value);
testMap3.put(i, value);
testMap4.put(i, value);
testMap5.put(i, value);
testMap6.put(i, value);
}
Map.Entry<Long, Integer>[] sortMap1 = new Map.Entry[testMap1.size()];
testMap1.entrySet().toArray(sortMap1);
Map.Entry<Long, Integer>[] sortMap2 = new Map.Entry[testMap2.size()];
testMap2.entrySet().toArray(sortMap2);
Map.Entry<Long, Integer>[] sortMap3 = new Map.Entry[testMap3.size()];
testMap3.entrySet().toArray(sortMap3);
Map.Entry<Long, Integer>[] sortMap4 = new Map.Entry[testMap4.size()];
testMap4.entrySet().toArray(sortMap4);
Map.Entry<Long, Integer>[] sortMap5 = new Map.Entry[testMap5.size()];
testMap5.entrySet().toArray(sortMap5);
Map.Entry<Long, Integer>[] sortMap6 = new Map.Entry[testMap6.size()];
testMap6.entrySet().toArray(sortMap6);
Comparator com = new Comparator<Map.Entry<Long, Integer>>() {
public int compare(Map.Entry<Long, Integer> o1, Map.Entry<Long, Integer> o2) {
Map.Entry<Long, Integer> t1 = o1;
Map.Entry<Long, Integer> t2 = o2;
Comparable<Integer> v1 = t1.getValue();
Integer v2 = t2.getValue();
if (v1 == null) {
if (v2 == null) {
return 0;
} else {
return -1;
}
} else {
if (v2 == null) {
return 1;
} else {
return v1.compareTo(v2);
}
}
}
};
long time1 = System.currentTimeMillis();
testMap1 = sortByMapValue(testMap1, SORT_TYPE_DEC);
long time10 = System.currentTimeMillis() - time1;
long time2 = System.currentTimeMillis();
bubbleSort(sortMap2, com);
long time20 = System.currentTimeMillis() - time2;
long time3 = System.currentTimeMillis();
quickSort(sortMap3, 0, sortMap3.length - 1, com);
long time30 = System.currentTimeMillis() - time3;
long time4 = System.currentTimeMillis();
heapSort(sortMap4, com);
long time40 = System.currentTimeMillis() - time4;
long time5 = System.currentTimeMillis();
shellSort(sortMap5, com);
long time50 = System.currentTimeMillis() - time5;
long time6 = System.currentTimeMillis();
Object[] mergeSortArray = mergeSort(sortMap6, com);
long time60 = System.currentTimeMillis() - time6;
System.out.println("sortByMapValue:" + time10 + "\nbubbleSort:" + time20 + "\nquickSort:" + time30
+ "\nheapSort:" + time40 + "\nshellSort:" + time50 + "\nmergeSort:" + time60);
}
/**
* 对map进行值排序
* @param map
* @param sortType
* @param <K>
* @param <V>
* @return
*/
public static <K, V extends Comparable<V>> Map<K, V> sortByMapValue(Map<K, V> map, final int sortType) {
if (map == null || map.size() == 0) {
return new LinkedHashMap<K, V>();
}
List<Map.Entry<K, V>> list = new LinkedList<Map.Entry<K, V>>(map.entrySet());
Collections.sort(list, new Comparator<Map.Entry<K, V>>() {
public int compare(Map.Entry<K, V> o1, Map.Entry<K, V> o2) {
Map.Entry<K, V> t1 = o1;
Map.Entry<K, V> t2 = o2;
//降序排列
if (sortType == SORT_TYPE_DEC) {
t1 = o2;
t2 = o1;
}
Comparable<V> v1 = t1.getValue();
V v2 = t2.getValue();
if (v1 == null) {
if (v2 == null) {
return 0;
} else {
return -1;
}
} else {
if (v2 == null) {
return 1;
} else {
return v1.compareTo(v2);
}
}
}
});
Map<K, V> result = new LinkedHashMap<K, V>();
Iterator<Map.Entry<K, V>> it = list.iterator();
while (it.hasNext()) {
Map.Entry<K, V> entry = it.next();
result.put(entry.getKey(), entry.getValue());
}
return result;
}
/**
* 冒泡排序
* @param targetArr
* @param <T>
*/
public static <T> void bubbleSort(T[] targetArr, Comparator<? super T> c) {
for(int i = 0; i < targetArr.length - 1; i++)
{
for(int j = targetArr.length - 1; j > i; j--)
{
if(c.compare(targetArr[j], targetArr[j - 1]) >= 0)
{
T temp = targetArr[j];
targetArr[j] = targetArr[j - 1];
targetArr[j - 1] = temp;
}
}
}
}
/**
* 快速排序
* @param targetArr
* @param start
* @param end
* @param <T>
*/
public static <T> void quickSort(T[] targetArr, int start, int end, Comparator<? super T> c) {
int i = start, j = end;
T key = targetArr[start];
while(i < j) {
//按 j -- 方向遍历目标数组,直到比 key 大的值为止
while(j > i && c.compare(targetArr[j], key) < 0) {
j --;
}
if(i < j) {
// targetArr[i] 已经保存在key中,可将后面的数填入
targetArr[i] = targetArr[j];
}
//按 i ++ 方向遍历目标数组,直到比 key 小的值为止
while(i < j && c.compare(targetArr[i], key) >= 0) {
i ++;
}
if(i < j) {
// targetArr[j] 已保存在targetArr[i]中,可将前面的值填入
targetArr[j] = targetArr[i];
}
}
// 此时 i == j
targetArr[i] = key;
if(i - start > 1) {
// 递归调用,把key前面的完成排序
quickSort(targetArr, start, i - 1, c);
}
if(end - j > 1) {
// 递归调用,把key后面的完成排序
quickSort(targetArr, j + 1, end, c);
}
}
/**
* 堆排序(最小堆)
* @param targetArr
* @param <T>
*/
public static <T> void heapSort(T[] targetArr, Comparator<? super T> c) {
buildMinHeapify(targetArr, c);
minHeapSort(targetArr, c);
}
/**
* 构建最小堆
* @param data
* @param <T>
*/
private static <T> void buildMinHeapify(T[] data, Comparator<? super T> c){
//没有子节点的才需要创建最小堆,从最后一个的父节点开始
int startIndex = getParentIndex(data.length - 1);
//从尾端开始创建最小堆,每次都是正确的堆
for (int i = startIndex; i >= 0; i--) {
minHeapify(data, data.length, i, c);
}
}
/**
* 创建最小堆
* @param data
* @param heapSize 需要创建最小堆的大小,一般在sort的时候用到,因为最多值放在末尾,末尾就不再归入最小堆了
* @param index 当前需要创建最小堆的位置
*/
private static <T> void minHeapify(T[] data, int heapSize, int index, Comparator<? super T> c){
// 当前点与左右子节点比较
int left = getChildLeftIndex(index);
int right = getChildRightIndex(index);
int largest = index;
if (left < heapSize && c.compare(data[index], data[left]) >= 0) {
largest = left;
}
if (right < heapSize && c.compare(data[largest], data[right]) >= 0) {
largest = right;
}
//得到最小值后可能需要交换,如果交换了,其子节点可能就不是最小堆了,需要重新调整
if (largest != index) {
T temp = data[index];
data[index] = data[largest];
data[largest] = temp;
minHeapify(data, heapSize, largest, c);
}
}
/**
* 排序,最大值放在末尾,data虽然是最小堆,在排序后就成了递增的
* @param data
*/
private static <T> void minHeapSort(T[] data, Comparator<? super T> c){
//末尾与头交换,交换后调整最小堆
for (int i = data.length - 1; i > 0; i--) {
T temp = data[0];
data[0] = data[i];
data[i] = temp;
minHeapify(data, i, 0, c);
}
}
/**
* 父节点位置
* @param current
* @return
*/
private static int getParentIndex(int current){
return (current - 1) >> 1;
}
/**
* 左子节点position 注意括号,加法优先级更高
* @param current
* @return
*/
private static int getChildLeftIndex(int current){
return (current << 1) + 1;
}
/**
* 右子节点position
* @param current
* @return
*/
private static int getChildRightIndex(int current){
return (current << 1) + 2;
}
/**
* 希尔排序
* @param targetArr
* @param <T>
*/
public static <T> void shellSort(T[] targetArr, Comparator<? super T> c) {
int d = targetArr.length;
while(d > 1){
d = d / 2;
for(int x = 0; x < d; x++){
for(int i = x + d; i < targetArr.length; i = i + d){
T temp = targetArr[i];
int j;
for(j = i - d; j >= 0 && c.compare(targetArr[j], temp) < 0; j = j - d){
targetArr[j + d] = targetArr[j];
}
targetArr[j + d] = temp;
}
}
}
}
/**
* 归并排序
* @param targetArr
* @param <T>
* @return
*/
public static <T> T[] mergeSort(T[] targetArr, Comparator<? super T> c) {
if (targetArr.length == 1) {
return targetArr;
} else {
T[] listL = (T[])new Object[targetArr.length / 2];
T[] listR = (T[])new Object[targetArr.length - targetArr.length / 2];
int Center = targetArr.length / 2;
for (int i = 0; i < Center; i++) {
listL[i] = targetArr[i];
}
for (int i = Center, j = 0; i < targetArr.length; i++, j++) {
listR[j] = targetArr[i];
}
T[] SortedListL= mergeSort(listL, c);
T[] SortedListR= mergeSort(listR, c);
T[] o_list = (T[])mergeTwoList(SortedListL, SortedListR, c);
if (o_list.length == targetArr.length) {
targetArr = o_list;
}
return o_list;
}
}
private static <T> T[] mergeTwoList(T[] listL, T[] listR, Comparator<? super T> c) {
int i = 0, j = 0;
T[] o_list = (T[])new Object[listL.length + listR.length];
int foot = 0;
while (i < listL.length && j < listR.length) {
if (c.compare(listL[i], listR[j]) >= 0) {
o_list[foot] = listL[i];
i++;
} else {
o_list[foot] = listR[j];
j++;
}
foot++;
}
if (i == listL.length) {
while (j < listR.length) {
o_list[foot++] = listR[j++];
}
} else { // j==listR.length
while (i < listL.length) {
o_list[foot++] = listL[i++];
}
}
return o_list;
}
}
排序速度:快排>shell>堆排>库函数排序>归并排序>冒泡排序