归并排序,其主要思想是通过递归来分解原有数组,通过使分解后的数组有序,然后合并数组从而达到排序的结果。因此我们不难写出整个归并排序的过程。

 

public static void mergeSort(int a[],int left,int right,int p[]){

if(left >= right){
return;
}else{

int mid = (right + left) >> 1;
mergeSort(a,left,mid,p);
mergeSort(a,mid+1,right,p);
mergeArray(a,left,mid,right,p);
}
}


这里定义了一个临时数组P,作用是将其临时比较后的数组存放到该数组中。通过mergeSort方法,来使原数组进行分解,这里进行递归调用。从而使分解后的两个数组里面最后只剩下一个元素。比较两个数组中的这个元素,谁大就将其先存放到临时数组P中,如果比较完毕后,其中一个数组已经为空,另外一个数组还有数据,那么将其元素直接复制到临时数组中。

 

分解完毕后,就要进行合并了。我们定义了mergeArray函数来进行合并。

 

public static void mergeArray(int a[],int first,int mid,int last,int temp[]){

int i = first, j = mid + 1;
int m = mid, n = last;
int k = 0;

while (i <= m && j <= n)
{
if (a[i] <= a[j])
temp[k++] = a[i++];
else
temp[k++] = a[j++];
}

while (i <= m)
temp[k++] = a[i++];

while (j <= n)
temp[k++] = a[j++];

for (i = 0; i < k; i++)
a[first + i] = temp[i];

}


在合并两个数组的过程中,使用while循环,这个while语句值得思考,两个数组,用其中一个数组的元素和另外一个进行循环比较,将较小的值存放到temp数组中,然后再比较下一个。其中一个数组比较完毕后,另一个数组中剩余的数据直接复制到临时数组中。

 

看看完整的代码。

 

package com.bplead.sort;

public class MergeSort {



public static void mergeSort(int a[],int left,int right,int p[]){

if(left >= right){
return;
}else{

int mid = (right + left) >> 1;
mergeSort(a,left,mid,p);
mergeSort(a,mid+1,right,p);
mergeArray(a,left,mid,right,p);
}
}

public static void mergeArray(int a[],int first,int mid,int last,int temp[]){

int i = first, j = mid + 1;
int m = mid, n = last;
int k = 0;

while (i <= m && j <= n)
{
if (a[i] <= a[j])
temp[k++] = a[i++];
else
temp[k++] = a[j++];
}

while (i <= m)
temp[k++] = a[i++];

while (j <= n)
temp[k++] = a[j++];

for (i = 0; i < k; i++)
a[first + i] = temp[i];
prt(temp);
}


private static void prt(int a[]){
for(int i=0;i<a.length;i++)
System.out.print(a[i] + " ");
System.out.println();
}

public static void main(String[] args) {
int a[] = {21,42,36,35,11,23,10,98,22,8,76,43,29,66,64,1};
int p[] = new int[a.length];
mergeSort(a,0,a.length-1,p);
prt(p);
}
}



 

运行的结果如下:

21 42 0 0 0 0 0 0 0 0 0 0 0 0 0 0 

35 36 0 0 0 0 0 0 0 0 0 0 0 0 0 0 

21 35 36 42 0 0 0 0 0 0 0 0 0 0 0 0 

11 23 36 42 0 0 0 0 0 0 0 0 0 0 0 0 

10 98 36 42 0 0 0 0 0 0 0 0 0 0 0 0 

10 11 23 98 0 0 0 0 0 0 0 0 0 0 0 0 

10 11 21 23 35 36 42 98 0 0 0 0 0 0 0 0 

8 22 21 23 35 36 42 98 0 0 0 0 0 0 0 0 

43 76 21 23 35 36 42 98 0 0 0 0 0 0 0 0 

8 22 43 76 35 36 42 98 0 0 0 0 0 0 0 0 

29 66 43 76 35 36 42 98 0 0 0 0 0 0 0 0 

1 64 43 76 35 36 42 98 0 0 0 0 0 0 0 0 

1 29 64 66 35 36 42 98 0 0 0 0 0 0 0 0 

1 8 22 29 43 64 66 76 0 0 0 0 0 0 0 0 

1 8 10 11 21 22 23 29 35 36 42 43 64 66 76 98 

1 8 10 11 21 22 23 29 35 36 42 43 64 66 76 98 


我这里有一个问题一直没想明白。就是在mergeArray中,为什么需要将临时数组中的值复制到原数组中。也就是

for (i = 0; i < k; i++)  

       a[first + i] = temp[i];

这一段代码的作用是什么,当我注释掉这段代码后,排序失败。请路过的高手指示一下。多谢。