归并排序

来源:互联网 发布:种族主义 知乎 编辑:程序博客网 时间:2024/05/21 13:21
自己实现的一个归并排序,加深下自己的理解...
归并排序应该是实用最多的吧,比快速排序慢,但是慢不了多少,它跟快速排序的时间是一个数量级,最重要的是它是稳定的,在至今的项目中,基本都实用归并排序
import java.util.List;public class MergeSort {@SuppressWarnings("unchecked")public static <T extends Comparable<? super T>> void sort(List<T> list) {if (list == null) {return;}Object[] src = (Object[]) list.toArray();Object[] dest = new Object[src.length];// 为了循环利用空间,true表示src为临时空间,false表示dest为临时空间// 因为一次归并后,临时空间的队列是结果boolean srcIsTmp = false;// 序列大小依次*2,进行归并排序for (int i = 1; i < list.size(); i *= 2) {if (srcIsTmp) {sort(dest, src, i);} else {sort(src, dest, i);}srcIsTmp = !srcIsTmp;}Object[] merged = srcIsTmp ? dest : src;list.clear();for (Object o : merged) {list.add((T) o);}}/** * 当小序列大小为n时,进行归并排序 * @param arr *            要排序的序列 * @param tmp *            临时序列,保存排序结果 * @param n *            序列大小 */private static void sort(Object[] arr, Object[] tmp, int n) {for (int i = 0; i < arr.length; i += 2 * n) {sort(arr, tmp, n, i);}}/** * 对相邻的两个序列进行归并排序 *  * @param arr *            要排序的序列 * @param tmp *            临时序列,保存排序结果 * @param n *            序列大小 * @param s *            序列1起始位置 */@SuppressWarnings({ "unchecked", "rawtypes" })private static void sort(Object[] arr, Object[] tmp, int n, int s) {// 序列1起始位置,包括int i1 = s;// 序列1结束位置,不包括int e1 = s + n;// 如果序列1为最后的序列,即序列2不存在if (e1 >= arr.length) {System.arraycopy(arr, s, tmp, s, arr.length - s);return;}// 序列2起始位置,包括int i2 = e1;// 序列2结束位置,不包括int e2 = Math.min(e1 + n, arr.length);// tmp序列下标int i = s;// 合并,比较两个队列while (i1 < e1 && i2 < e2) {if (((Comparable) arr[i1]).compareTo(arr[i2]) > 0) {tmp[i++] = arr[i2++];} else {tmp[i++] = arr[i1++];}}// 复制剩余的队列for (int j = i1; j < e1; j++) {tmp[i++] = arr[j];}for (int j = i2; j < e2; j++) {tmp[i++] = arr[j];}}}


原创粉丝点击