排序算法--归并排序

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

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

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


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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值