上篇通用类型的两路归并算法实现(二)——面向接口实现通用类型的两路归并,我们通过Comparable接口实现了对任意实现了Comparable接口的类型对象数组的排序,但我们发现仍然有一些类,比如JDK或者第三方类库中的类,他们并没有实现Comparable接口,我们不方便修改源码,而且讲道理,我们也不应该修改这些类的源码。针对这些类型,我们又应该如何对他们进行排序呢?
答案就是今天的Comparator接口,来,话不多说,直接上代码感受下社会Comparator哥的魅力。
import java.util.Arrays;
import java.util.Comparator;
/*
*通用类型的两路归并算法实现
*/
public class GenericMergeSort {
/**
* 对数组array中start到end之间元素进行排序
* @param array 待排序数组
* @param start 排序起始索引
* @param end 排序截止索引
* @return 输出有序数组
*/
public static <T> T[] sort(T[] array, int start, int end, Comparator<T> comparator) {
int mid = (start + end) / 2;
if (start < end) {
// 左边有序
sort(array, start, mid,comparator);
// 右边有序
sort(array, mid + 1, end,comparator);
// 左右归并
merge(array, start, mid, end,comparator);
}
return array;
}
public static <T> void merge(T[] array, int start, int middle, int end,Comparator<T> comparator) {
//用于存储中间结果
Object[] temp = new Object[end - start + 1];
//分别代表a,b,temp临时数组的下标指示器
int i = start;
int j = middle + 1;
int k = 0;
// 把较小的数先移到中间结果数组中
while (i <= middle && j <= end) {
if (comparator.compare(array[i],array[j])<0) {
temp[k++] = array[i++];
} else {
temp[k++] = array[j++];
}
}
//判定a数组是否有剩余,如果有将a数组剩余元素放入结果数组
while (i <= middle) {
temp[k++] = array[i++];
}
//判定b数组是否有剩余,如果有将b数组剩余元素放入结果数组
while (j <= end) {
temp[k++] = array[j++];
}
// 将中间结果写入到最终结果中
for (int l = 0; l < temp.length; l++) {
array[l + start] = (T) temp[l];
}
}
}
对于任意需要排序的类型A,我们只需要实现一个Compator<A>,并在compare方法中实现相应的比较逻辑即可。友情提示:用Java 8的lambda表达式实现最佳。
好了,本系列通用类型的两路归并实现就说到这儿,希望大家能真实地体会到面向对象编程和面向接口编程的魅力。
created by 刘Sir