归并排序的主要思想就是将一个待排序列,①不断地一分为二划分红一个元素组成序列,一个元素组成的序列也就是有序序列,②而后再合并将相邻的两个有序序列,最终待排序列变成一个有序序列。
总之,归并算法就是采用了分治+递归的思想,先递归分解数列,而后再合并数列。算法
以待排序列3,2,5,6,4,7,1为例数组
将此序列一分为二
①:3,2,5 和 6,4,7,1
而后将①左边序列3,2,5一分为二3d
②:3 和 2,5
继续划分②左边序列,由于只有一个元素3,因此3已是有序序列,返回到②将右边序列一分为二code
③:2 和 5
由于③的左边和右边序列均只有一个元素因此都是有序序列,就能够进行左右相邻序列的合并操做,此时合并后的序列为2,5。而后,返回到②合并序列3和2,5为有序序列2,3,5blog
而后返回到①,将①右边的序列一分为二排序
④:6,4 和 7,1
将④的左边继续一分为二递归
⑤:6 和 4
由于⑤的左右两边序列均为一个元素,也就是都是有序的,那么就将这两个相邻序列进行合并,合并后的序列为4,6,返回到④,将④右边的序列进行一分为二ast
⑥:7 和 1
由于⑥的左右两边序列均为一个元素,因此都是有序序列,将这两个序列合并,合并后为1,7
而后回到④,合并④的左右两边有序序列4,6和1,7,合并后为1,4,6,7class
最后回到①,如今①的左右两边均为有序序列,2,3,5 和 1,4,6,7,合并这两个序列,合并后就为1,2,3,4,5,6,7 im
对应上述文字分析,附图一张,可对照理解
根据描述,将代码实现就可分为如下两部分:
//要从新开辟空间存储排好序的数据 bool MergeSort(int a[],int n) { int * temp = new int[n]; if(NULL == temp) return false; mergesort(a,0,n-1,temp); delete[] temp; return true; } void mergesort(int a[],int first,int last,int temp[]) { if(first<last) { int mid = (first+last)/2;//将一个数组一分为二 mergesort(a,first,mid,temp);//左边有序 mergesort(a,mid+1,last,temp);//右边有序 mergearray(a,first,mid,last,temp);//合并两个数组 } }
//将一个数组一分为二看作两个数组,将有二个有序数列a[first...mid]和a[mid...last]合并。 void mergearray(int a[],int first,int mid,int last,int temp[]) { int i = first,j = mid+1; int n = mid, m = last; int k = 0; while(i<=n && j<=m) { if(a[i]<a[j]) temp[k++] = a[i++]; else temp[k++] = a[j++]; } while(i <= n) temp[k++] = a[i++]; while(j <= m) temp[k++] = a[j++]; for(i=0;i<k;i++)//将排好序的值赋给原数组 a[first+i] = temp[i]; }