归并排序是建立在归并操作上的一种有效的排序算法,该算法是采用分治法的一个非常典型的应用。将已有序的子序列合并,得到完全有序的序列;即先使每个子序列有序,再使子序列段间有序。若将两个有序表合并成一个有序表,称为二路归并。归并过程为:比较a[i]和b[j]的大小,若a[i]≤b[j],则将第一个有序表中的元素a[i]复制到r[k]中,并令i和k分别加上1;否则将第二个有序表中的元素b[j]复制到r[k]中,并令j和k分别加上1,如此循环下去,直到其中一个有序表取完,然后再将另一个有序表中剩余的元素复制到r中从下标k到下标t的单元。归并排序的算法我们通常用递归实现,先把待排序区间[s,t]以中点二分,接着把左边子区间排序,再把右边子区间排序,最后把左区间和右区间用一次归并操作合并成有序的区间[s,t]。
归并是将两个已排序合并成一个更大的已排序文件的过程,将输入序列分成两部分并递归处理每一部分。当子问题解决后,算法又将子问题的解合并。归并排序是从最小子文件开始并以最大子文件结束的。如下图所示,归并排序,先将序列对半分割,并不断递归对半分割,直到每一部分只剩一个元素,然后进行归并,即对多个子序列进行归并处理。
代码:
public class MergeSort {
public static int[] mergeSort(int[] A,int[] temp,int left,int right)
{
int mid;
if(right>left)
{
mid=left+(right-left)/2;//不直接使用(right+left)/2是防止溢出
//对mid左右两边的序列进行递归分割
mergeSort(A,temp,left,mid);
mergeSort(A,temp,mid+1,right);
//对分割到不能分割的序列进行归并
Merge(A,temp,left,mid+1,right);
print(A);
}
return A;
}
//以下是归并的过程
private static void Merge(int[] A,int[] temp,int left,int mid,int right)
{
//以mid为界将数组分为两个数组,然后通过依次两个数组的数值大小,依次存入临时数组temp实现归并。
int i,left_end,size,temp_pos;
left_end=mid-1;
temp_pos=left;
size=right-left+1;
while((left<=left_end)&&(mid<=right))
{
if(A[left]<=A[mid])
{
temp[temp_pos]=A[left];
temp_pos=temp_pos+1;
left=left+1;
}
else
{
temp[temp_pos]=A[mid];
temp_pos+=1;
mid+=1;
}
}
while(left<=left_end)
{
temp[temp_pos]=A[left];
left+=1;
temp_pos+=1;
}
while(mid<=right)
{
temp[temp_pos]=A[mid];
mid+=1;
temp_pos+=1;
}
for(i=0;i<size;i++)
{
A[right]=temp[right];
right-=1;
}
}
private static void print(int[] A)
{
int n=A.length;
for(int i=0;i<n;i++)
System.out.print(A[i]+" ");
System.out.println();
}
public static void main(String[] args) {
// TODO Auto-generated method stub
int[] A= {9,10,6,4,29,34,25,13,14,17,8,5};
int n=12;
int right=11;
int left=0;
int[] temp=new int[n];
System.out.println("归并排序的序列变化:");
int[] ans=MergeSort.mergeSort(A, temp, left, right);
System.out.println("归并排序后的序列:");
for(int i=0;i<n-1;i++)
System.out.print(ans[i]+" ");
System.out.print(ans[n-1]);
}
}
测试结果:
归并排序的序列变化:
9 10 6 4 29 34 25 13 14 17 8 5
6 9 10 4 29 34 25 13 14 17 8 5
6 9 10 4 29 34 25 13 14 17 8 5
6 9 10 4 29 34 25 13 14 17 8 5
4 6 9 10 29 34 25 13 14 17 8 5
4 6 9 10 29 34 13 25 14 17 8 5
4 6 9 10 29 34 13 14 25 17 8 5
4 6 9 10 29 34 13 14 25 8 17 5
4 6 9 10 29 34 13 14 25 5 8 17
4 6 9 10 29 34 5 8 13 14 17 25
4 5 6 8 9 10 13 14 17 25 29 34
归并排序后的序列:
4 5 6 8 9 10 13 14 17 25 29 34
归并排序以连续的方式访问数据,适用于链表排序;归并排序对输入的初始次序不敏感。当数据量十分大时,快排、选择等内部排序无法进行时,可以使用外部排序中的多路归并完成排序。归并排序的时间复杂度为O(nlogn),排序的效率较高。
转发请注明:转自http://blog.csdn.net/carson0408/article/details/78653021