合并排序

package com.victor.sort.algorithms;

import java.util.ArrayList;

import com.victor.sort.seeds.*;

/**
 * 合并排序
 * @author 黑妹妹牙膏
 *
 */
public class Merge extends SortAlgorithms {

	/**
	Algorithm
	# split in half
	m = n / 2

	# recursive sorts
	sort a[1..m]
	sort a[m+1..n]

	# merge sorted sub-arrays using temp array
	b = copy of a[1..m]
	i = 1, j = m+1, k = 1
	while i <= m and j <= n,
	    a[k++] = (a[j] < b[i]) ? a[j++] : b[i++]
	    → invariant: a[1..k] in final position
	while i <= m,
	    a[k++] = b[i++]
	    → invariant: a[1..k] in final position
	Properties
	■Stable 
	■Θ(n) extra space for arrays (as shown) 
	■Θ(lg(n)) extra space for linked lists 
	■Θ(n&middot;lg(n)) time 
	■Not adaptive 
	■Does not require random access to data 
	Discussion
	Merge sort is very predictable. It makes between 0.5*lg(n) and lg(n) comparisons per element, and between lg(n) and 1.5*lg(n) swaps per element. The minima are achieved for already sorted data; the maxima are achieved, on average, for random data. If using Θ(n) extra space is of no concern, then merge sort is an excellent choice: It is simple to implement, and it is the only stable O(n&middot;lg(n)) sorting algorithm. Note that when sorting linked lists, merge sort requires only Θ(lg(n)) extra space (for recursion). 

	Merge sort is the algorithm of choice for a variety of situations: when stability is required, when sorting linked lists, and when random access is much more expensive than sequential access (for example, external sorting on tape). 

	There do exist linear time in-place merge algorithms for the last step of the algorithm, but they are both expensive and complex. The complexity is justified for applications such as external sorting when Θ(n) extra space is not available. 
	*/
	
	@Override
	protected ArrayList<Integer> doSort(ArrayList<Integer> Alist) {
		return mergeSort(Alist,0,Alist.size()-1);
	}
	
	private ArrayList<Integer> mergeSort(ArrayList<Integer> Alist,int from,int end)
	{
		ArrayList<Integer> a = Alist;
		
		if(end<=from) return a;
		if(end-from==1)
		{
			int Vfrom = a.get(from);
			int Vend = a.get(end);
			if(Vend<Vfrom)
			{
				a.set(from, Vend);
				a.set(end, Vfrom);
				moveMentIncrease();
			}
			return a;
		}
		int n = end-from+1;
		
		//split to two part
		int m = n/2+from;
		
		//sort a1 and a2
		a = mergeSort(a,from, m-1);
		a = mergeSort(a,m, end);
		
		//merge
		
		ArrayList<Integer> b = copy(a,from,m);
		int i = 0, j = m, k = from;
		while( i < m-from && j < end+1)
		{
			//a[k++] = (a[j] < b[i]) ? a[j++] : b[i++]
		    a.set(k++, a.get(j) < b.get(i)?a.get(j++) : b.get(i++));
		    moveMentIncrease();
		}
		while (i < m-from)
		{
			//a[k++] = b[i++]
			a.set(k++, b.get(i++));
			moveMentIncrease();
		}
		return a;
	}
	
	public void print(ArrayList<Integer> a,int i,int j,int k)
	{
		System.out.println("#######################################");
		for(int index=0;index<a.size();index++)
		{
			String output = "";
			if(index==k)
			{
				output = "["+index+"]: "+a.get(index);
			}
			else
			{
				output = index+": "+a.get(index);
			}
			if(index == i)
			{
				output = output + " <- i";
			}
			if(index == j)
			{
				output = output + " <- j";
			}
			System.out.println(output);
		}
		System.out.println("#######################################");
	}
	
	private ArrayList<Integer> copy(ArrayList<Integer> source,int from,int end)
	{
		ArrayList<Integer> result = new ArrayList<Integer>();
		if(from <0) return result;
		if(end < from) return result;
		if(end >= source.size()) return result;
		for(int i=from;i<end;i++)
		{
			result.add(source.get(i));
		}
		return result;
	}

	@Override
	public String getName() {
		return "Merge";
	}
	
	public static void main(String[] args)
	{
		Seeds seed1 = new Random();
		Seeds seed2 = new NearSorted();
		Seeds seed3 = new Reversed();
		Seeds seed4 = new FewUniqueKeys();
		SortAlgorithms SA = new Merge();
		SA.sort(seed1,10000);
		//SA.print();
		SA.sort(seed2,10000);
		SA.sort(seed3,10000);
		SA.sort(seed4,10000);
	}

}


你可能感兴趣的:(java,排序算法,合并排序)