稳定排序:归并排序

归并排序:对于给定的一组长度为n的记录,利用分治和递归的思想,将记录分为一个个长度为1的子序列,最后再用递归方法将排好序的子序列合并成为越来越大的有序序列。此方法称为2-路归并排序

  • 归并排序一般会用在外部排序的算法中。
  • 该算法是采分治法的一个非常典型的应用。

【时间复杂度】:O(nlogn)

【最优情况】:   O(nlogn)

【最坏情况】:O(nlogn)

(归并排序的形式就是一棵二叉树,它需要遍历的次数就是二叉树的深度,而根据完全二叉树的可以得出它的时间复杂度是O(n*log2n)。)

【空间复杂度】:O(n)

(算法处理过程中,需要一个大小为n的临时存储空间用以保存合并序列。)

实现代码

C++:

#include <stdio.h>
#define MAXSIZE 10

void MergeSort(int[] a,num){
//num数组长度
int *list1=k;
int list1_size=num/2;
int *list2=k+num/2;
int list2_size=num-list1_size;
//分解数组:原数组分为左数组和右数组,左数组再调用该函数,继续细分下去
//只要数组的长度大于1,它就会继续分解下去
if(num>1){
MergeSort(list1,list1_size);
MergeSort(list2,list2_size);
Merging(list1,list1_size,list2,list2_size);
}
//排序数组并归并

void Merging(*list1,list1_size,*list2,list2_size){

int i,j,k;//i是list1的下标,j是list2的下标,k是临时数组的下标
i=j=k=0;
int[]tmp=new int[MAXSIZE];
while(i<list1_size&&j<list2_size){

if(list1[i]<list2[j]){
tmp[k++]=list1[i++];
}else
tmp[k++]=list2[j++];
}
//list1数组中还有未扫描的元素
while(i<list1_size){
tmp[k++]=list1[i++];

}

//list2数组中还有未扫描的元素
 while(j<list2_size){
  tmp[k++]=list2[j++];
}
//临时数组覆盖原数组
for(int n=0;n<(list1_size+list2_size);n++){
  list1[n]=tmp[n];

 }

}

java

扫描二维码关注公众号,回复: 11992689 查看本文章


//java实现
public class Sort{

  //分解 、递归
  public static void MergeSort(int[] a,int left,int right){
   int mid=(left+right)/2;
   if(left<right){
     //left,right是数组的下标
     //完整的数组分成左右两半,左边的数组再调用此方法,再细分下去
      MergeSort(a,left,mid);
      MergeSort(a,mid+1,right);
    //两两数组归并
      Merging(a,left,mid,right);

   }

 }
  //归并 排序方法
  /*
   将排好序的元素放进临时数组
   因为最后临时数组都是排好序的
   所以就可以覆盖原有数组

 */
  public static void Merging(int[]a,int left,int mid,int right){
    int[] tmp=new int[right-left+1];//临时数组存放排好序的元素
    int i=left;//左边数组的下标
    int j=mid+1;//右边数组的下标
    int k=0;//临时数组的下标
   while(i<=mid&&j<=right){
    if(a[i]<a[j]){
     tmp[k]=a[i];
     i++;
     k++;
   }
  //左边数组还有没扫描完的元素
   while(i<=mid){
    //tmp[k++]=a[i++]
     tmp[k]=a[i];
     i++;
     k++;
  }
 //右边数组还有没扫描完的元素
   while(j<=right){
   //tmp[k++]=a[j++]
     tmp[k]=a[j];
     j++;
     k++;
   }
   //将临时数组覆盖到原数组中
   for(int n=0;n<tmp.length;n++){
     num[n+low]=tmp[n];
  }
 }
 public static void main(String[]args){
  int[]a={10,55,13,23,5,22,87,34};
  MergeSort(a);


 }
}


心得:因为归并排序是个比较复杂的排序算法,实际操作着将一组记录用归并排序来排序,可以理解,但是用代码实现起来挺不容易的,因为用到了递归和分治思想。自己先后用了C++和java来实现归并排序,发现其实c++可能更好理解,因为c++有指针,而java并没有,所以在java的代码中设置了mid这个变量作为中间索引,两种语言的写法还是不太一样的


猜你喜欢

转载自blog.csdn.net/sinat_35803474/article/details/70260122