package org.xlj.algorithm.order; import java.util.List; /** * 排序算法 */ public class Orders { /** * 冒泡排序第一种,实际不是真正的冒泡排序,因为没有"两两比较",更应该是简单交换 * @param list * @param <T> */ public static<T> void bubbleSort0(List<T> list, Compare<T> compare) { for(int i=0; i < list.size(); i++) { for(int j=i + 1; j < list.size(); j++) { if(compare.compare(list.get(i), list.get(j)) > 0) { Orders.swap(list, i, j); } } } } /** * 真正的冒泡排序 * @param list * @param <T> */ public static <T> void bubbleSort(List<T> list, Compare<T> compare) { for(int i=0; i < list.size(); i++) { for(int j=list.size() - 1; j > i; j--) { if(compare.compare(list.get(j - 1), list.get(j)) > 0) { Orders.swap(list, j - 1, j); } } } } /** * 冒泡排序的优化,如果有一次操作没有进行交换则直接返回 * @param <T> */ public static <T> void bubbleSort1(List<T> list, Compare<T> compare) { boolean hasSwap = false; for (int i=0; i < list.size(); i++) { hasSwap = false; for(int j=list.size() - 1; j > i; j--) { if(compare.compare(list.get(j - 1), list.get(j)) > 0) { Orders.swap(list, j - 1, j); hasSwap = true; } } if(!hasSwap) { break; } } } /** * 选择排序 * @param list * @param compare * @param <T> */ public static <T> void selectSort(List<T> list, Compare<T> compare) { // int n=0; int min = 0; for (int i=0; i < list.size(); i++) { min = i; for(int j=i+1; j < list.size(); j++) { if(compare.compare(list.get(i), list.get(j)) > 0) { min = j; } // n++; } if(min != i) { Orders.swap(list, i, min); } } // System.out.println(n); } /** * 插入排序 * @param <T> */ public static <T> void insertSort(List<T> list, Compare<T> compare) { // int n=0; //哨兵 T sentinel = null; for(int i=1; i < list.size(); i++) { if(compare.compare(list.get(i-1), list.get(i)) > 0) { sentinel = list.get(i); int left = i-1; for(; left >= 0 && compare.compare(list.get(left), sentinel) > 0; left--) { list.set(left + 1, list.get(left)); // n++; } list.set(left + 1, sentinel); } } // System.out.println(n); } /** * 快速排序 * @param list * @param compare * @param <T> */ public static<T> void quickSort(List<T> list, Compare<T> compare) { Orders.qSort(list, compare, 0, list.size() - 1); // System.out.println(cs + " " + ms); } // static int cs = 0, ms = 0; public static<T> void qSort(List<T> list, Compare<T> compare, int left, int right) { // cs++; // ms = cs>ms? cs: ms; int pivotIndex = 0; // if(left < right && (right - left) > 50) // if(left < right) // { // pivotIndex = Orders.partition(list, compare, left, right); // Orders.qSort(list, compare, left, pivotIndex - 1); // Orders.qSort(list, compare, pivotIndex + 1, right); // } // else // { // Orders.insertSort(list, compare); // } while (left < right) { pivotIndex = Orders.partition(list, compare, left, right); Orders.qSort(list, compare, left, pivotIndex - 1); left = pivotIndex + 1; } // cs--; } public static<T> int partition(List<T> list, Compare<T> compare, int left, int right) { // cs++; // ms = cs>ms? cs: ms; //枢轴对象 T pivot = list.get((int)(Math.random() % (right - left) + left)); // T pivot = list.get(left); while (left < right) { while(left < right && compare.compare(pivot, list.get(right)) <= 0 ) { right--; } //左右交换位置 // Orders.swap(list, left, right); //优化只做替换不做交换 list.set(left, list.get(right)); while (left < right && compare.compare(list.get(left), pivot) <= 0) { left++; } //左右交换位置 // Orders.swap(list, left, right); //优化只做替换不做交换 list.set(right, list.get(left)); } //优化还原枢轴到中间 list.set(left, pivot); // cs--; return left; } // /** // * 快排 // * @param list // * @param compare // * @param <T> // */ // public static <T> void quickSort(List<T> list, Compare<T> compare) // { // Orders.qSort(list, compare, 0, list.size() - 1); System.out.println(n); // } // // /** // * 快排递归 // * @param list // * @param compare // * @param compare // * @param high // * @param <T> // */ // private static <T> void qSort(List<T> list, Compare<T> compare, int low, int high) // { // int pivot = 0; // if(low < high) // { // pivot = Orders.partition(list, compare, low, high); // qSort(list, compare, low, pivot - 1); // qSort(list, compare, pivot + 1, high); // } // } // static int n = 0; // // /** // * 分区 // * @param <T> // * @return // */ // private static <T> int partition(List<T> list, Compare<T> compare, int low, int high) // { // T pivotKey = list.get(low); // // while (low < high) // { // while (low < high && compare.compare(list.get(high), pivotKey) >= 0) // { // high--; n++; // } // swap(list, low, high); // // while (low < high && compare.compare(list.get(low), pivotKey) <= 0) // { // low++; n++; // } // swap(list, low, high); // } // // //低值段的最后一个作为下一次递归的分界线 // return low; // } /** * 交换列表的对应的两个对象 * @param list * @param one * @param two * @param <T> */ public static<T> void swap(List<T> list, int one, int two) { T temp = list.get(one); list.set(one, list.get(two)); list.set(two, temp); } /** * 比较 * @param <T> */ public interface Compare<T> { /** * 比较两个对象 * @param t1 * @param t2 * @return <0 左边小, == 0 相等, >0 左边大 */ int compare(T t1, T t2); } }
package org.xlj.algorithm.order; import org.junit.After; import org.junit.Before; import org.junit.Test; import java.text.SimpleDateFormat; import java.util.ArrayList; import java.util.Calendar; import java.util.Date; import java.util.List; public class OrdersTest { int length = 100000; Date date; @Before public void befor() { this.date = new Date(); } @After public void after() { System.out.println(new Date().getTime() - this.date.getTime()); System.out.println(); this.date = new Date(); } /** * bubbleSort0 * 44420 * * bubbleSort * 44852 * * bubbleSort1 * 42483 * * selectSort * 22094 * * insertSort * 14392 */ @Test public void testAll() { this.bubbleSort0Test(); System.out.println("bubbleSort0"); this.after(); this.bubbleSortTest(); System.out.println("bubbleSort"); this.after(); this.bubbleSort1Test(); System.out.println("bubbleSort1"); this.after(); this.selectSortTest(); System.out.println("selectSort"); this.after(); this.insertSortTest(); System.out.println("insertSort"); this.after(); } @Test public void bubbleSort0Test() { List<Integer> list = this.getTestList(); Orders.bubbleSort0(list, this.getTestCompare()); // System.out.println(list); } @Test public void bubbleSortTest() { List<Integer> list = this.getTestList(); Orders.bubbleSort(list, this.getTestCompare()); // System.out.println(list); } @Test public void bubbleSort1Test() { List<Integer> list = this.getTestList(); Orders.bubbleSort1(list, this.getTestCompare()); // System.out.println(list); } @Test public void selectSortTest() { List<Integer> list = this.getTestList(); Orders.selectSort(list, this.getTestCompare()); // System.out.println(list); } @Test public void insertSortTest() { List<Integer> list = this.getTestList(); Orders.insertSort(list, this.getTestCompare()); // System.out.println(list); } @Test public void quickSortTest() { List<Integer> list = this.getTestList(); // list.clear(); // list.add(5); // list.add(9); // list.add(4); // list.add(8); // list.add(3); // list.add(7); // list.add(2); Orders.quickSort(list, this.getTestCompare()); // System.out.println(list); } /** * 获取测试比较器 * @return */ private Orders.Compare<Integer> getTestCompare() { return new Orders.Compare<Integer>() { @Override public int compare(Integer t1, Integer t2) { return t1 == t2? 0: t1 > t2 ? 1 : -1; } }; } /** * 获取测试列表 * @return */ private List<Integer> getTestList() { List<Integer> list = new ArrayList<>(); for(int i=0; i < this.length; i++) { list.add(length - i); // list.add(i + 1); // list.add((int)(Math.random() * this.length)); } // System.out.println(list); return list; } @Test public void swapTest() { List<Integer> list = new ArrayList<>(); list.add(0); list.add(1); Orders.swap(list, 0, 1); assert(list.get(0) == 1); assert(list.get(1) == 0); } }