Sort and Shuffle 排序和打乱
来源:互联网 发布:java web小项目下载 编辑:程序博客网 时间:2024/05/16 09:31
排序可视化
Sort 排序:
定义数组排序的基本方法:
public abstract class ArraySort {public static boolean INCREASE = true;public static boolean DECREASE = false;protected static <T extends Comparable<? super T>> boolean compare(T a,T b, boolean order, Comparator<T> comparator) {int cmp = COMPARE(a, b, comparator);if (order == INCREASE) {return cmp < 0;} else {return cmp > 0;}}public static <T extends Comparable<? super T>> int COMPARE(T a, T b,Comparator<T> comparator) {if (comparator != null) {return comparator.compare(a, b);} else {return a.compareTo(b);}}protected static void swap(Object[] array, int i, int j) {Object temp = array[i];array[i] = array[j];array[j] = temp;}public static <T extends Comparable<? super T>> boolean isSorted(T[] array) {return isSorted(array, INCREASE, null);}public static <T extends Comparable<? super T>> boolean isSorted(T[] array,boolean order) {return isSorted(array, order, null);}public static <T extends Comparable<? super T>> boolean isSorted(T[] array,Comparator<T> comparator) {return isSorted(array, INCREASE, comparator);}public static <T extends Comparable<? super T>> boolean isSorted(T[] array,boolean order, Comparator<T> comparator) {for (int i = 1; i < array.length; i++) {if (compare(array[i], array[i - 1], order, comparator)) {return false;}}return true;}public <T extends Comparable<? super T>> void sort(T[] array) {sort(array, INCREASE, null);}public <T extends Comparable<? super T>> void sort(T[] array, boolean order) {sort(array, order, null);}public <T extends Comparable<? super T>> void sort(T[] array,Comparator<T> comparator) {sort(array, INCREASE, comparator);}public abstract <T extends Comparable<? super T>> void sort(T[] array,boolean order, Comparator<T> comparator);}
排序基于Decision Tree,算法至少NlogN。
In-place是说sort用的memory不超过 c*logN.
凡是长距离swap的都是unstable的。
HeapSort 对于cash memory的利用很差,特别是大数组的情况。
1. Selection Sort 选择排序:
每次在剩余的元素中选择最小的,和当前待定排序位置的元素交换位置。Unstable, in-place, O(N^2)
public class SelectionSort extends ArraySort {@Overridepublic <T extends Comparable<? super T>> void sort(T[] array,boolean order, Comparator<T> comparator) {for (int i = 0; i < array.length - 1; i++) {int base = i;for (int j = i + 1; j < array.length; j++) {if (compare(array[j], array[base], order, comparator)) {base = j;}}swap(array, i, base);}}}
2. Insertion Sort 插入排序:
每次将当前元素放到已排序队列的合适位置,利用元素交换,自后向前,逐个比较。Stable, in-palce, O(N^2)
public class InsertionSort extends ArraySort {@Overridepublic <T extends Comparable<? super T>> void sort(T[] array,boolean order, Comparator<T> comparator) {for (int i = 1; i < array.length; i++) {int j = i;while (j > 0) {if (compare(array[j], array[j - 1], order, comparator)) {swap(array, j, j - 1);--j;} else {break;}}}}}
3. Shell Sort:
每次将给定间隔的元素进行插入排序,间隔为3x+1。 Unstable, in-place, O(N^1.5)
public class ShellSort extends ArraySort {@Overridepublic <T extends Comparable<? super T>> void sort(T[] array,boolean order, Comparator<T> comparator) {int N = array.length;int step = 1;while (step < N / 3) {step = 3 * step + 1;}while (step >= 1) {for (int i = step; i < N; i++) {for (int j = i; j >= step&& compare(array[j], array[j - step], order, comparator); j -= step) {swap(array, j, j - step);}}step = step / 3;}}}
4. Merge Sort 归并排序:
树形结构,依次将两个有序数组合并成一个。Stable, O(NlgN)
O(N) = O(N/2)+O(N/2)+N
Top-down 递归:
public class MergeSort extends ArraySort {// Recursive Merge Sort@Overridepublic <T extends Comparable<? super T>> void sort(T[] array,boolean order, Comparator<T> comparator) {@SuppressWarnings("unchecked")T[] aux = (T[]) new Comparable[array.length];sort(array, aux, 0, array.length - 1, order, comparator);}private static <T extends Comparable<? super T>> void merge(T[] array,T[] aux, int start, int mid, int end, boolean order,Comparator<T> comparator) {int i = start;int j = mid + 1;int k = start;while (true) {if (compare(array[j], array[i], order, comparator)) {aux[k++] = array[j++];} else {aux[k++] = array[i++];}if (i == mid + 1) {while (j <= end) {aux[k++] = array[j++];}break;}if (j == end + 1) {while (i <= mid) {aux[k++] = array[i++];}break;}}System.arraycopy(aux, start, array, start, end - start + 1);}private static <T extends Comparable<? super T>> void sort(T[] array,T[] aux, int start, int end, boolean order, Comparator<T> comparator) {if (end - start + 1 < 8) {insertionSort(array, start, end, order, comparator);return;}int mid = start + ((end - start) >> 1);sort(array, aux, start, mid, order, comparator);sort(array, aux, mid + 1, end, order, comparator);if (!compare(array[mid + 1], array[mid], order, comparator)) {return;}merge(array, aux, start, mid, end, order, comparator);}private static <T extends Comparable<? super T>> void insertionSort(T[] array, int start, int end, boolean order,Comparator<T> comparator) {for (int i = start; i <= end; i++) {for (int j = i; j > 0; j--) {if (compare(array[j], array[j - 1], order, comparator)) {swap(array, j, j - 1);} else {break;}}}}}
Divide and Conquer 方法。aux作为辅助数组用于暂存,只作一次声明。less(后,前)来保证stable。每次merge后要将aux拷贝回原array。
优化:
1. 当数组长度小于8时用插入排序。
2. 两段排序后,当第一段最后的元素不大于第二段第一个元素时,不用merge。
Bottom-up merge sort 非递归:
public static <T extends Comparable<? super T>> void sortBU(T[] array, boolean order, Comparator<T> comparator) {int N = array.length;@SuppressWarnings("unchecked")T[] aux = (T[]) new Comparable[array.length];for (int size = 1; size < N; size <<= 1) {for (int start = 0; start < N - size; start += size << 1) {merge(array, aux, start, start + size - 1, Math.min(start + (size << 1) - 1, N - 1), order, comparator);}}}
树形结构自下而上,每两个相邻大小为size的数组进行归并。end要注意,最后一个数组大小够不够size。
5. Quick Sort 快排:
每次分割两部分,左边都比分割点小,右边都比分割点大。
普通Quick Sort:
public class QuickSort extends ArraySort {/**** Normal Quick Sort ****/@Overridepublic <T extends Comparable<? super T>> void sort(T[] array, boolean order, Comparator<T> comparator) {sort(array, 0, array.length - 1, order, comparator);}private static <T extends Comparable<? super T>> void sort(T[] array,int start, int end, boolean order, Comparator<T> comparator) {if (end - start + 1 <= 10) {insertionSort(array, start, end, order, comparator);return;}int mid = partition(array, start, end, order, comparator);sort(array, start, mid - 1, order, comparator);sort(array, mid + 1, end, order, comparator);}private static <T extends Comparable<? super T>> int partition(T[] array,int start, int end, boolean order, Comparator<T> comparator) {int i = start;int j = end + 1;while (true) {// array[start] >= array[++i]while (compare(array[++i], array[start], order, comparator)) {if (i == end) {break;}}// array[start] < array[--j]while (compare(array[start], array[--j], order, comparator)) {if (j == start) {break;}}if (i >= j) {break;}swap(array, i, j);}swap(array, start, j);return j;}private static <T extends Comparable<? super T>> void insertionSort(T[] array, int start, int end, boolean order,Comparator<T> comparator) {for (int i = start; i <= end; i++) {for (int j = i; j > 0; j--) {if (compare(array[j], array[j - 1], order, comparator)) {swap(array, j, j - 1);} else {break;}}}}}
3-way Quick Sort:
循环中分割点一直移动,与分割点相等的元素会和分割点排在一起。有利于处理duplicate。
public static <T extends Comparable<? super T>> void sort3Way(T[] array,boolean order, Comparator<T> comparator) {sort3(array, 0, array.length - 1, order, comparator);}public static <T extends Comparable<? super T>> void sort3(T[] array,int start, int end, boolean order, Comparator<T> comparator) {if (end - start + 1 <= 10) {insertionSort(array, start, end, order, comparator);return;}int lt = start;int gt = end;T v = array[start];int i = start;while (i <= gt) {int cmp = COMPARE(array[i], v, comparator);if (order == INCREASE) {if (cmp < 0) {swap(array, lt++, i++);} else if (cmp > 0) {swap(array, i, gt--);} else {i++;}} else {if (cmp < 0) {swap(array, i, gt--);} else if (cmp > 0) {swap(array, lt++, i++);} else {i++;}}}sort3(array, start, lt - 1, order, comparator);sort3(array, gt + 1, end, order, comparator);}
6. 堆排序
建立最大堆,然后依次把堆顶元素放到末尾。
public static <T extends Comparable<T>> void sort(T[] array) {int tail = array.length - 1;// 建立heapfor (int i = array.length / 2 - 1; i >= 0; i--) {percolateDown(array, i, tail);}// 排序。依次将最大值移除堆放在数组末尾。通过tail控制堆大小while(tail > 0) {swap(array, 0, tail--);percolateDown(array, 0, tail);}}private static <T extends Comparable<T>> void percolateDown(T[] array, int k, int tail) {// 初始化max为左childint max = k * 2 + 1;if (max > tail) {return;}// 如果右child存在,且大,则max为右child。if (max + 1 <= tail && array[max + 1].compareTo(array[max]) > 0) {max = max + 1;}if (array[k].compareTo(array[max]) < 0) {swap(array, k, max);k = max;percolateDown(array, k, tail);}}private static <T> void swap(T[] array, int i, int j) {T temp = array[i];array[i] = array[j];array[j] = temp;}
Shuffle 打乱:
定义接口:
public interface MyShuffle {public <T> void shuffle(T[] array);}
1. Sort Shuffle 排序打乱:
将每个元素给定一个随机值,将值排序,则元素被打乱
public class SortShuffle implements MyShuffle {@Overridepublic <T> void shuffle(T[] array) {int N = array.length;HashMap<Double, T> map = new HashMap<Double, T>();double[] val = new double[N];for (int i = 0; i < N; i++) {val[i] = Math.random() + Math.random();map.put(val[i], array[i]);}Arrays.sort(val);for (int i = 0; i < N; i++) {array[i] = map.get(val[i]);}}}
2. Knuth Shuffle 逐步打乱:
每次当前元素和前面(含自身)的元素随机交换。
public class KnuthShuffle implements MyShuffle {public static <T> void swap(T[] array, int i, int j) {T temp = array[i];array[i] = array[j];array[j] = temp;}@Overridepublic <T> void shuffle(T[] array) {int N = array.length;Random rand = new Random();for (int i = 1; i < N; i++) {swap(array, i, rand.nextInt(i + 1));}}}
Select 选择:
在数组中选择大小为第k的数字。
定义接口:
public interface MySelect {// Check if a < bpublic default <T extends Comparable> boolean less(T a, T b) {// public default boolean less(Comparable a, Comparable b)return a.compareTo(b) < 0;}public default <T> boolean less(T a, T b, Comparator<T> comparator) {return comparator.compare(a, b) == -1;}// Swap i and j in arraypublic default <T> void swap(T[] array, int i, int j) {T temp = array[i];array[i] = array[j];array[j] = temp;}// Sort methodpublic <T> Comparable<T> select(Comparable<T>[] array, int k);public <T> T select(T[] array, int k, Comparator<T> comparator);}
1. Quick Select 快速选择:
基于Quick Select 快排。
public class QuickSelect implements MySelect {@Overridepublic <T> Comparable<T> select(Comparable<T>[] array, int k) {int start = 0;int end = array.length - 1;while (start < end) {int mid = partition(array, start, end);if (mid < k) {start = mid + 1;} else if (mid > k) {end = mid - 1;} else {return array[k];}}return array[k];}@Overridepublic <T> T select(T[] array, int k, Comparator<T> comparator) {int start = 0;int end = array.length - 1;while (start < end) {int mid = partition(array, start, end, comparator);if (mid < k) {start = mid + 1;} else if (mid > k) {end = mid - 1;} else {return array[k];}}return array[k];}private <T> int partition(Comparable<T>[] array, int start, int end) {int i = start;int j = end + 1;while (true) {// array[start] >= array[++i]while (less(array[++i], array[start])) {if (i == end) {break;}}// array[start] < array[--j]while (less(array[start], array[--j])) {if (j == start) {break;}}if (i >= j) {break;}swap(array, i, j);}swap(array, start, j);return j;}private <T> int partition(T[] array, int start, int end,Comparator<T> comparator) {int i = start;int j = end + 1;while (true) {// array[start] >= array[++i]while (less(array[++i], array[start], comparator)) {if (i == end) {break;}}// array[start] < array[--j]while (less(array[start], array[--j], comparator)) {if (j == start) {break;}}if (i >= j) {break;}swap(array, i, j);}swap(array, start, j);return j;}}
0 0
- Sort and Shuffle 排序和打乱
- 打乱数组排序的算法shuffle
- C++ -- shuffle 和 random_shuffle 随机打乱
- Hadoop MapReduce Shuffle and Sort
- Map-Reduce: Shuffle and Sort
- Hadoop 之 Shuffle and Sort
- javascript shuffle 打乱数组
- python random.shuffle(随机打乱列表等) 和 random.random
- Shuffle和排序
- Mapreduce shuffle和排序
- Mapreduce shuffle和排序
- Mapreduce shuffle和排序
- shuffle和排序
- Shuffle和排序
- Mapreduce shuffle和排序
- Shuffle和排序
- 第28课:彻底解密Spark Sort-Based Shuffle排序具体实现内幕和源码详解
- 将数组打乱 shuffle 函数
- Fly-By Topology
- ACM_Floyd-Warshall (Floyd) 算法
- keySet 与entrySet 遍历HashMap性能差别
- 光标
- GTK中如何捕捉和屏蔽按键信号(如F10等)
- Sort and Shuffle 排序和打乱
- 可穿戴设备(CC2541)上微信(8)
- hdu 4289 Control (最小割 sap)
- Redis总体介绍
- python进阶四:类的继承
- POJ_1107_WsCipher
- mysql命令大全
- Memcached简单介绍
- Android 屏幕旋转 处理 AsyncTask 和 ProgressDialog 的最佳方案