二路归并排序

 归并排序介绍 
        前面我们讲了堆排序,因为它用到了完全二叉树,充分利用了完全二叉树的深度是⌊log2n⌋+1的特性,所以效率比较高。不过堆结构的设计本身是比较复杂的,老实说,能想出这样的结构就挺不容易,有没有更直接简单的办法利用完全二叉树来排序呢?当然是有。 
        先来举一个例子。你们知道高考一本、二本、专科分数线是如何划分出来的吗? 
        简单地说,如果各高校本科专业在某省高三理科学生中计划招收1万名,那么将全省参加高考的理科学生分数倒排序,第1万名的总分数就是当年本科生的分数线(现实可能会比这复杂,这里简化之)。也就是说,即使你是你们班级第一、甚至年级第一名,如果你没有上分数线,则说明你的成绩排不到全省前1万名,你也就基本失去了当年上本科的机会了。 
        换句话说,所谓的全省排名,其实也就是每个市、每个县、每个学校、每个班级的排名合并后再排名得到的。注意我这里用到了合并一词。 
我们要比较两个学生的成绩高低是很容易的,比如甲比乙分数低,丙比丁分数低。那么我们也就可以很容易得到甲乙丙丁合并后的成绩排名,同样的,戊己庚辛的排名也容易得到,由于他们两组分别有序了,把他们八个学生成绩合并有序也是很容易做到的了,继续下去……最终完成全省学生的成绩排名,此时高考状元也就诞生了。 
        为了更清晰地说清楚这里的思想,大家来看图9-8-1,我们将本是无序的数组序列 {16,7,13,10,9,15,3,2,5,8,12,1,11,4,6,14},通过两两合并排序后,再合并,最终获得了一个有序的数组。注意仔细观察它的形状,你会发现,它像极了一棵倒置的完全二叉树,通常涉及到完全二叉树结构的排序算法,效率一般都不低的——这就是我们要讲的归并排序法。

归并排序算法 
        “归并”一词的中文含义就是合并、并入的意思,而在数据结构中的定义是将两个或两个以上的有序表组合成一个新的有序表。 
归并排序(Merging Sort)就是利用归并的思想实现的排序方法。它的原理是假设初始序列含有n个记录,则可以看成是n个有序的子序列,每个子序列的长度为1,然后两两归并,得到⌈n/2⌉(⌈x⌉表示不小于x的最小整数)个长度为2或1的有序子序列;再两两归并,……,如此重复,直至得到一个长度为n的有序序列为止,这种排序方法称为2路归并排序。

image

我的代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
public  static  void  MergeSort( int  array[], int  begin, int  end)
     {
         if (begin==end) return ;       //注意结束条件!!!不能丢 如果begin==end则结束
         int  mid=(begin+end)/ 2 ;
         MergeSort(array,begin,mid);   //递归归并排列数组的前半部分
         MergeSort(array,mid+ 1 ,end);   //递归归并排列数组的后半部分
         Merge(array,begin,mid,end);   //两个有序数组进行merge  
         
     }
     public  static  void  Merge( int  array[], int  begin , int  mid, int  end)
     {
         if (begin==end) return ;
         int  a1=begin,a2=mid+ 1 ,a=begin;     //a1是前半部分数组指针,a2是后半部分数组指针,a是临时数组指针
         int  temp[] = new  int [array.length];
         while (a1<=mid && a2<=end)         {
             if (array[a1]<array[a2]) temp[a++]=array[a1++];
             else  temp[a++]=array[a2++];
         }
         while (a1<=mid)   //前半数组中剩余的值赋给temp
         {
             temp[a++]=array[a1++];     
         }
         while (a2<=end)  //后半数组中剩余的值赋给temp
         {
             temp[a++]=array[a2++]; 
         }
         for ( int  i=begin;i<=end;i++)
         {
             array[i]=temp[i];
         }
 
     }
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值