倒腾(sort 排序)

来源:互联网 发布:我是淘宝卖家怎么收钱 编辑:程序博客网 时间:2024/06/06 13:57

排序中的sort一般为初始,sort2或者merge2之类的都是改进版。

模板

package com.duoduo.sort;import com.duoduo.std.StdIn;import com.duoduo.std.StdOut;import com.duoduo.util.RedirectionIn;public class Example {public static void sort(Comparable[] a) {}private static boolean less(Comparable v, Comparable w) {return v.compareTo(w) < 0;}private static void exch(Comparable[] a, int i, int j) {Comparable t = a[i];a[i] = a[j];a[j] = t;}private static void show(Comparable[] a) {for (int i = 0; i < a.length; i++) {StdOut.print(a[i] + " ");}StdOut.println();}public static boolean isSorted(Comparable[] a) {for (int i = 1; i < a.length; i++) {if (less(a[i], a[i - 1])) {return false;}}return true;}public static void main(String args[]) {RedirectionIn.fileToStdIn("data/words.txt");String[] a = StdIn.readAllStrings();RedirectionIn.close();sort(a);assert isSorted(a);show(a);}}

比较器

package com.duoduo.sort;import java.util.Arrays;import com.duoduo.std.StdOut;import com.duoduo.std.StdRandom;import com.duoduo.std.StopWatch;public class SortCompare {public static double time(String alg, Double[] a) {StopWatch timer = new StopWatch();if (alg.equals("Insertion")) {Insertion.sort(a);}if (alg.equals("Selection")) {Selection.sort(a);}if (alg.equals("Shell")) {Shell.sort(a);}if (alg.equals("ArraySort")) {Arrays.sort(a);}return timer.elapsedTime();}public static double timeRandomInput(String alg, int N, int testTimes) {double total = 0.0;Double[] a = new Double[N];for (int i = 0; i < testTimes; i++) {for (int j = 0; j < N; j++) {a[j] = StdRandom.uniform();}total += time(alg, a);}return total;}public static void main(String args[]) {String alg1 = "Shell";// String alg2 = "Selection";String alg2 = "Insertion";String alg3 = "ArraySort";int N = 200000;int testTimes = 1;double t1 = timeRandomInput(alg1, N, testTimes);double t2 = timeRandomInput(alg2, N, testTimes);double t3 = timeRandomInput(alg3, N, testTimes);StdOut.printf("%d个测试数据 算法:%s(%.7f)", N, alg1, t1);StdOut.printf("是算法:%s(%.7f) 的%.2f倍", alg2, t2, t2 / t1);StdOut.printf("\n算法:%s(%.7f)", alg3, t3);}}/* * 100000个测试数据 算法:Shell(0.4370000)是算法:Insertion(185.6230000) 的424.77倍 * 算法:ArraySort(0.2190000) */

选择排序

sort2较少交换次数

package com.duoduo.sort;import com.duoduo.std.StdIn;import com.duoduo.std.StdOut;import com.duoduo.util.RedirectionIn;import com.duoduo.util.RedirectionOut;public class Selection {public static void sort(Comparable[] a) {int N = a.length;int min;for (int i = 0; i < N; i++) {min = i;for (int j = i + 1; j < N; j++) {if (less(a[j], a[min])) {min = j;}}exch(a, min, i);}}public static void sort2(Comparable[] a) {int N = a.length;int min;for (int i = 0; i < N - 1; i++) {min = i;for (int j = i + 1; j < N; j++) {if (less(a[j], a[min])) {min = j;}}if (min != i) {exch(a, min, i);}}}private static boolean less(Comparable v, Comparable w) {return v.compareTo(w) < 0;}private static void exch(Comparable[] a, int i, int j) {Comparable t = a[i];a[i] = a[j];a[j] = t;}private static void show(Comparable[] a) {for (int i = 0; i < a.length; i++) {StdOut.print(a[i] + " ");}StdOut.println();}public static boolean isSorted(Comparable[] a) {for (int i = 1; i < a.length; i++) {if (less(a[i], a[i - 1])) {return false;}}return true;}public static void main(String args[]) {RedirectionIn.fileToStdIn("data/words.txt");String[] a = StdIn.readAllStrings();RedirectionIn.close();sort2(a);assert isSorted(a);show(a);}}

插入排序

sort2找到位置全部移动

package com.duoduo.sort;import com.duoduo.std.StdIn;import com.duoduo.std.StdOut;import com.duoduo.util.RedirectionIn;public class Insertion {public static void sort(Comparable[] a) {int N = a.length;for (int i = 1; i < N; i++) {for (int j = i; j > 0 && (less(a[j], a[j - 1])); j--) {exch(a, j, j - 1);}}}public static void sort2(Comparable[] a) {int N = a.length;int j;for (int i = 1; i < N; i++) {Comparable temp = a[i];for (j = i; j > 0 && less(temp, a[j - 1]); j--) {a[j] = a[j - 1];}if (j != i) {a[j] = temp;}}}private static boolean less(Comparable v, Comparable w) {return v.compareTo(w) < 0;}private static void exch(Comparable[] a, int i, int j) {Comparable t = a[i];a[i] = a[j];a[j] = t;}private static void show(Comparable[] a) {for (int i = 0; i < a.length; i++) {StdOut.print(a[i] + " ");}StdOut.println();}public static boolean isSorted(Comparable[] a) {for (int i = 1; i < a.length; i++) {if (less(a[i], a[i - 1])) {return false;}}return true;}public static void main(String args[]) {RedirectionIn.fileToStdIn("data/words.txt");String[] a = StdIn.readAllStrings();RedirectionIn.close();sort2(a);assert isSorted(a);show(a);}}

自上而下归并

sort2

java 6 中归并也用到了:只要a[mid] <= a[mid+1],就不调用merge()方法,以为如果条件成立,则mid前边数组的最大值小于mid后面数组的最小值,则a[lo..mid..hi]已经有序。

merge2 快速归并:按降序将a[]的后部分复制到aux[],然后在归并会a[],这样会去掉内循环中检测某半边是否用尽的代码,不过排序是不稳定的。

package com.duoduo.sort;import java.util.Arrays;import com.duoduo.std.StdIn;import com.duoduo.std.StdOut;import com.duoduo.util.RedirectionIn;public class MergeSort {private static Comparable[] aux;public static void sort(Comparable[] a) {aux = new Comparable[a.length];sort2(a, 0, a.length - 1);}private static void sort(Comparable[] a, int lo, int hi) {if (lo >= hi) {return;}int mid = lo + (hi - lo) / 2;sort(a, lo, mid);sort(a, mid + 1, hi);merge(a, lo, mid, hi);}private static void sort2(Comparable[] a, int lo, int hi) {if (lo >= hi) {return;}int mid = lo + (hi - lo) / 2;sort(a, lo, mid);sort(a, mid + 1, hi);if (less(a[mid + 1], a[mid])) {merge2(a, lo, mid, hi);}}/*** * 将a[lo..mid]与a[mid+1..hi]归并 * **/public static void merge(Comparable[] a, int lo, int mid, int hi) {int i = lo;int j = mid + 1;for (int k = lo; k <= hi; k++) {aux[k] = a[k];}for (int k = lo; k <= hi; k++) {// 左边已经木有了if (i > mid) {a[k] = aux[j++];}// 右边木有了else if (j > hi) {a[k] = aux[i++];} else if (less(aux[i], aux[j])) {a[k] = aux[i++];} else {a[k] = aux[j++];}}}public static void merge2(Comparable[] a, int lo, int mid, int hi) {int i = lo;int j = hi;for (int k = lo; k <= mid; k++) {aux[k] = a[k];}//后半段逆序复制,消除边界判断判断int m = mid + 1;for (int k = hi; k > mid; k--) {aux[m++] = a[k];}for (int k = lo; k <= hi && lo <= hi; k++) {if (less(aux[i], aux[j])) {a[k] = aux[i++];} else {a[k] = aux[j--];}}}private static boolean less(Comparable v, Comparable w) {return v.compareTo(w) < 0;}private static void exch(Comparable[] a, int i, int j) {Comparable t = a[i];a[i] = a[j];a[j] = t;}private static void show(Comparable[] a) {for (int i = 0; i < a.length; i++) {StdOut.print(a[i] + " ");}StdOut.println();}public static boolean isSorted(Comparable[] a) {for (int i = 1; i < a.length; i++) {if (less(a[i], a[i - 1])) {return false;}}return true;}public static void main(String args[]) {RedirectionIn.fileToStdIn("data/words.txt");String[] a = StdIn.readAllStrings();RedirectionIn.close();sort(a);Arrays.sort(a);assert isSorted(a);show(a);}}

自下而上归并

package com.duoduo.sort;import java.util.Arrays;import com.duoduo.std.StdIn;import com.duoduo.std.StdOut;import com.duoduo.util.RedirectionIn;public class MergeUpSort {private static Comparable[] aux;public static void sort(Comparable[] a) {int N = a.length;aux = new Comparable[N];// sz为子数组大小for (int sz = 1; sz < N; sz *= 2) {// 一次排俩子数组for (int lo = 0; lo < N - sz; lo += sz * 2) {merge(a, lo, lo + sz - 1, Math.min(lo + sz * 2 - 1, N - 1));}}}public static void merge(Comparable[] a, int lo, int mid, int hi) {int i = lo;int j = mid + 1;for (int k = lo; k <= hi; k++) {aux[k] = a[k];}for (int k = lo; k <= hi; k++) {if (i > mid) {a[k] = aux[j++];} else if (j > hi) {a[k] = aux[i++];} else if (less(aux[i], aux[j])) {a[k] = aux[i++];} else {a[k] = aux[j++];}}}private static boolean less(Comparable v, Comparable w) {return v.compareTo(w) < 0;}private static void exch(Comparable[] a, int i, int j) {Comparable t = a[i];a[i] = a[j];a[j] = t;}private static void show(Comparable[] a) {for (int i = 0; i < a.length; i++) {StdOut.print(a[i] + " ");}StdOut.println();}public static boolean isSorted(Comparable[] a) {for (int i = 1; i < a.length; i++) {if (less(a[i], a[i - 1])) {return false;}}return true;}public static void main(String args[]) {// RedirectionIn.fileToStdIn("data/words.txt");// String[] a = StdIn.readAllStrings();// RedirectionIn.close();char[] aa = "EASYQUESTION".toCharArray();Character[] a = new Character[aa.length];for (int i = 0; i < aa.length; i++) {a[i] = aa[i];}sort(a);assert isSorted(a);show(a);}}