• 排序算法--归并排序


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

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

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


  • 相关阅读:
    2018-2019-1 20165212 《信息安全系统设计基础》第九周学习总结
    12321
    实现mybash
    2018-2019-1 20165212 《信息安全系统设计基础》第八周学习总结(pwd)
    2018-2019-1 20165212 实验三-并发程序设计
    2018-2019-1 20165212 20165222 20165313 实验二 固件程序设计
    2018-2019-1 20165212 《信息安全系统设计基础》第1次实验——实验环境的熟悉
    开根号(二分法、牛顿法)
    logistic回归的损失函数是什么形式?为什么?为什么不选平方损失函数?
    西瓜书课后习题——第六章
  • 原文地址:https://www.cnblogs.com/riskyer/p/3266547.html
Copyright © 2020-2023  润新知