归并排序

自己实现的一个归并排序,加深下自己的理解...
归并排序应该是实用最多的吧,比快速排序慢,但是慢不了多少,它跟快速排序的时间是一个数量级,最重要的是它是稳定的,在至今的项目中,基本都实用归并排序


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];
		}
	}

}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值