Comparable跟Comparator引发的思考

Comparable和Comparator引发的思考

最近在学习Comparable和Comparator 的区别,在学习的过程中发现,如果单从表明现象来理解这两个东西是比较费劲的。于是写了两个Demo,一步一步的查看这两个种的内部实现原理,其实绕来绕去都是使用TimSort 对一个数组进行排序。如果要想更轻松的理解对Comparable和Comparator 的使用,我们可以将其简单的缩略为普通插入排序来理解,让插入元素和有序区从前到后的一个个元素进行比较Compare(将要插入的元素,Element O) 或者 插入元素.CompareTo(Element O),当两个Compare结果小于0时 ,交换两个元素,所有中间元素后移一位,使有序区有序。关键在于compare结果小于0,交换来定制排序。知道这个简单原理之后,我们就可以更娴熟利用Comparable和Comparator来定制自己的排序了。

TimSort就是二分插入排序和优化版的归并排序的结合体。当数组元素数量小于某个值时,采用二分插入排序时间复杂度为O(N*lgN),当数据大的时候采用更为高效的归并排序。

这里我贴出二分插入排序的算法:

package binary_insertion;

public class BinaryInsertionDemo {

	/**
	 * @param args
	 */
	public static void main(String[] args) {
		int[] a = {5,4,3,2,1};
		sort(a, 0, a.length, 0);
		
		for (int s : a) {
			System.out.print(s + " ");
		}
	}
	//二分插入排序  时间复杂度O(N*lgN)
	static void sort(int[] a, int lo, int hi, int start) {
        if (start == lo)
            start++;
        for ( ; start < hi; start++) {
            int pivot = a[start];

            // Set left (and right) to the index where a[start] (pivot) belongs
            int left = lo;
            int right = start;
            assert left <= right;
     
            while (left < right) {
                int mid = (left + right) >>> 1;
                if (pivot - a[mid] < 0)
                	right = mid;
                else
                    left = mid + 1;
            }

            int n = start - left;  
            switch (n) {
                case 2:  a[left + 2] = a[left + 1];
                case 1:  a[left + 1] = a[left];
                         break;
                default: System.arraycopy(a, left, a, left + 1, n);
            }
            a[left] = pivot;
        }
    
	}

}

对于优化版的归并排序,后续再研究。。。