最近在学习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; } } }
对于优化版的归并排序,后续再研究。。。
时间: 2024-10-08 17:45:23