合并排序

归并排序是利用递归和分而治之的技术将数据序列划分成为越来越小的半子表,再对半子表排序,最后再用递归步骤将排好序的半子表合并成为越来越大的有序序列,归并排序包括两个步骤,分别为:

  1)划分子表

  2)合并半子表

  首先我们来讨论归并算法,归并算法将一系列数据放到一个向量中,索引范围为[first,last],这个序列由两个排好序的子表构成,以索引终点(mid)为分界线,以下面一个序列为例

  7,10,19,25,12,17,21,30,48

  这样的一个序列中,分为两个子序列 7,10,19,25  和 12,17,21,30,48,如下图所示:

 
     image
 
  再使用归并算法的时候的步骤如下:
 
  第一步:比较v[indexA]=7和v[indexB]=12,将较小的v[indexA]取出来放到临时向量tempArray中,然后indexA加1
  
image
 
 
   第二步:比较v[indexA]=10和v[indexB]=12,将较小的10放到临时变量tempArray中,然后indexA++;
 
   image
 
  第三步:比较v[indexA]=19与v[indexB]=12,将较小的12存放到临时变量tempArray中,然后indexB++;
 
    image
 
  第四步到第七步:按照以上规则,进行比对和 存储,得到如下结果:

image 

最后一步:将子表b中剩余项添加到临时向量tempArray中

 
     image
 
  然后将临时变量中的值按照索引位置,拷贝回向量v中,就完成了对向量v的归并排序
   Java实现代码:
  package com.sort.merge;
  public class Merge {
  /**
  * 分治法,自顶向下,递归分割数组,最终归并
  */
  public static void merge(int[] arr,int start,int end){
  if(start<end){
  int mid = (start+end)/2;
  merge(arr,start,mid);//递归地对arr[start...mid]排序
  merge(arr,mid+1,end);//递归地对arr[mid+1...end]排序
  doMerge(arr,start,mid,end);//组合,将两个有序区合并为一个有序区
  }
  }
  //组合,归并
  public static void doMerge(int[] arr,int start,int mid,int end){
  int tempIndex = start;
  int Index = start;
  int right = mid + 1;
  int temp[] = new int[arr.length];
  //两个子序列比较,小的放入临时数组
  while(start <= mid && right <= end){
  if(arr[start] <= arr[right]){
  temp[tempIndex++] = arr[start++];
  }else{
  temp[tempIndex++] = arr[right++];
  }
  }
  //剩下的右边的元素加入临时数组
  while(start <= mid){
  temp[tempIndex++] = arr[start++];
  }
  //剩下的右边的元素加入临时数组
  while(right <= end){
  temp[tempIndex++] = arr[right++];
  }
  //复制临时数据temp[]中的数据到arr[]数组
  while(Index < end){
  arr[Index] = temp[Index++];
  }
  }
  public static void main(String[] args) {
  // TODO Auto-generated method stub
  int arr[] = {2,4,6,8,1,3,5,9};
  merge(arr,0,arr.length-1);
  for (int i = 0; i < arr.length; i++) {
  System.out.print(arr[i]);
  }
  }
  }
  采用分治法进行自顶向下的算法设计,形式更为简洁。
  (1)分治法的三个步骤
  设归并排序的当前区间是R[low..high],分治法的三个步骤是:
  ①分解:将当前区间一分为二,即求分裂点
  ②求解:递归地对两个子区间R[low..mid]和R[mid+1..high]进行归并排序;
  ③组合:将已排序的两个子区间R[low..mid]和R[mid+1..high]归并为一个有序的区间R[low..high]。
  递归的终结条件:子区间长度为1(一个记录自然有序)。
  (2)具体算法
  void MergeSortDC(SeqList R,int low,int high)
  {//用分治法对R[low..high]进行二路归并排序
  int mid;
  if(low<high){//区间长度大于1
  mid=(low+high)/2; //分解
  MergeSortDC(R,low,mid); //递归地对R[low..mid]排序
  MergeSortDC(R,mid+1,high); //递归地对R[mid+1..high]排序
  Merge(R,low,mid,high); //组合,将两个有序区归并为一个有序区
  }
  }//MergeSortDC

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值