c/c++--归并排序

归并排序,思想是将两个有序的数组归并成一个有序的数组。

它的时间复杂度是NlogN。


归并排序同时是分治算法的很好体现。

因为归并的前提是左右两边数组是有序的,因此我们得从最小的每两个长度开始进行归并,然后每4个长度开始归并,以此类推。

在较小长度的数组中,归并排序的效率无法证明与希尔排序的是快是慢,但是在较长长度的时候,是优于希尔排序的。


首先先理解归并的方法:

[java]  view plain  copy
  在CODE上查看代码片 派生到我的代码片
  1. /** 
  2.  * 归并方法 
  3.  * @param a[] 一个有序的数组 
  4.  * @param low 最低位下标 
  5.  * @param mid 中间位下标 
  6.  * @param height 最高位下标 
  7.  */  
  8. public static void merge(int[] a,int[] copyA, int low, int mid ,int height){  
  9.   
  10.     //复制到一个新的数组  
  11.     for(int i=low;i<=height;i++){  
  12.         copyA[i] = a[i];  
  13.     }  
  14.     //归并操作  
  15.     //右边数组的第一个位置  
  16.     int j = mid + 1;  
  17.     for(int i=low;i<=height;i++){  
  18.         //左边已经完全归并完成,右边的是有序的,因此只要把右边未归并完第一个放到a  
  19.         // j++ 代表j当前位置被归并,然后处理下一个位置  
  20.         if(i > mid){  
  21.             a[i] = copyA[j++];  
  22.         }else if(j > height){//右边已经被归并完成  
  23.             a[i] = copyA[i++];  
  24.         }else if(copyA[i] < copyA [j]){  
  25.             a[i] = copyA[i];  
  26.         }else{  
  27.             a[i] = copyA[j];  
  28.         }  
  29.     }  
  30. }  


自上而下的递归归并:

我们通过递归的方法自上而下递归调用自己:

[java]  view plain  copy
  在CODE上查看代码片 派生到我的代码片
  1. /** 
  2.      * 递归归并,自上而下的归并,从数组长度的一半开始,通过递归,当长度为2、4、8.。。。开始归并 
  3.      * @param a 
  4.      */  
  5.     public static void sort1(int[] a){  
  6.         int[] copyA = new int[a.length];  
  7.         sort(a,copyA,0,a.length-1);  
  8.         SortTest.isSorted(a);  
  9.     }  
  10.       
  11.     /** 
  12.      * 这里通过递归的方式,当长度间隔为1的时候开始归并,然后再是2,4、、、、 
  13.      * @param a 
  14.      * @param copyA 
  15.      * @param low 
  16.      * @param height 
  17.      */  
  18.     public static void sort(int[] a,int[] copyA, int low,int height){  
  19.         if(low >= height){  
  20.             return ;  
  21.         }  
  22.         int mid = (low + height)/2;  
  23.         //归并前半部分  
  24.         sort(a,copyA,low,mid);  
  25.         //归并后半部分  
  26.         sort(a,copyA,mid+1,height);  
  27.         merge(a,copyA,low,mid,height);  
  28.     }  

它的过程如下:


自下而上的归并:

[java]  view plain  copy
  在CODE上查看代码片 派生到我的代码片
  1. /** 
  2.      * 自下而上的归并,直接从长度间隔为1开始 
  3.      * @param a 
  4.      */  
  5.     public static void sort2(int[] a){  
  6.         int[] copyA = new int[a.length];  
  7.         //复制到一个新的数组  
  8.         for(int i=0;i<=a.length-1;i++){  
  9.             copyA[i] = a[i];  
  10.         }  
  11.         //i代表循环次数  
  12.         //e.g:0 1 2 3 4 5 6的循环过程是:  
  13.         //01 23 45 6 --> 0123 456 --> 0123456  
  14.         //次数为3次,因此i<=a.length/2  
  15.         for(int i =0;i<=a.length/2;i++){  
  16.             //j为具体归并的两个元素的下标  
  17.             for(int j=0;j<a.length -i;j++){  
  18.                 merge(a,copyA,j,(j+j+i+1)/2,j+i+1-1);  
  19.             }  
  20.         }  
  21.         SortTest.isSorted(a);  
  22.     }  
它的过程如下:



原文地址:http://blog.csdn.net/qq_25412055/article/details/53472086?ref=myread

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值