用Java泛型实现归并排序(递归和非递归算法)

package ch10;

public class MergeSort {
	/**
	 * 二路归并排序的递归算法-入口
	 * @param 
	 * @param t
	 * @return
	 */
	public static  boolean mergeSortRecursive(T[] t){
		if(t==null || t.length <= 1) return true;
		
		MSortRecursive(t, 0, t.length-1);
		
		return true;
	}
	
	/**
	 * 二路归并排序的递归算法-递归主体
	 * @param 
	 * @param t
	 * @param low
	 * @param high
	 * @return
	 */
	private static  boolean MSortRecursive(T[] t, int low, int high){
		if(t==null || t.length <= 1 || low == high) return true;
		
		int mid = (low+high)/2;
		MSortRecursive(t, low, mid);
		MSortRecursive(t, mid+1, high);
		merge(t, low, mid ,high);
		
		return true;
	}
	
	/**
	 * 2-路归并排序的非递归算法。
	 * 算法思路:
	 * 从归并段的长度为1开始,一次使归并段的长度变为原来的2倍。
	 * 在每趟归并的过程中,要注意处理归并段的长度为奇数和
	 * 最后一个归并段的长度和前面的不等的情况
	 * @param 
	 * @param t
	 * @return
	 */
	public static  boolean mergeSortNonRecursive(T[] t){
		if(t==null || t.length<=1) return true;
		
		int len = 1;
		//程序边界的处理非常重要
		while(len <= t.length){
			for(int i = 0 ; i+len<=t.length-1 ;i += len*2){
				int low = i, mid = i+len-1, high = i+len*2-1;
				if(high>t.length-1) high = t.length-1;
				merge(t, i, mid, high);
			}
			
			len *= 2;
		}
		return true;
	}
	
	
	/**
	 * 将两个归并段合并成一个归并段
	 * @param 
	 * @param t
	 * @param low
	 * @param mid
	 * @param high
	 * @return
	 */
	private static  boolean merge(T[] t, int low, int mid, int high){		
		T[] s = t.clone();//先复制一个辅助数组
		
		int i, j, k;//三个指示器,i指示t[low...mid],j指示t[mid+1...high],k指示s[low...high]
		for(i=low, j=mid+1, k=low ; i<=mid && j<=high ; k++){
			if(t[i].compareTo(t[j]) <= 0){
				s[k] = t[i++];
			}else{
				s[k] = t[j++];
			}
		}
		
		//将剩下的元素复制到s中
		if(i <= mid){
			for( ; k <= high; k++){
				s[k] = t[i++];
			}
		}else{
			for( ; k<=high; k++){
				s[k] = s[j++];
			}
		}
		for(int m = low; m<=high ; m++){//将辅助数组中的排序好的元素复制回原数组
			t[m] = s[m];
		}
		
		return true;
	}
	
	public static void main(String[] args) {
		Integer[] arr = new Integer[]{2,3,6,8,9,2,0,1};
		long startTime=System.currentTimeMillis();   //获取开始时间
		mergeSortRecursive(arr);
		long endTime=System.currentTimeMillis();   //获取开始时间
		System.out.println("执行时间:"+(endTime-startTime));
		for(int i : arr){
			System.out.println(i);
		}
	}
}

你可能感兴趣的:(数据结构)