排序系列算法——归并排序
归并排序是采用分治策略进行排序的一种算法,其基本原理是将未排序的数组划分为两个子数组,分别对两个子数组尽心排序,然后将有序的子数组合并。归并排序分为两个过程:一是数组划分为两个子数组并分别进行排序,二是将两个已排序的子数组进行合并。
将数组划分为两个子数组并进行排序
将数组一分为二很简单,关键是划分之后如何排序的问题。归并排序的做法是对数组不断进行划分,直到不能划分为止或者说不需要划分为止,怎样才算不需要再划分呢?当子数组只剩下一个或者两个的时候就不用继续划分了,一个元素本来就是有序的,两个元素只要对比一下双方的大小就可以轻而易举的完成排序的工作。当两个子数组都是有序时,将两个字数组合并成为一个有序的数组,然后不断重复字数组合并的工作就可以完成原始数组的排序。
以一个实例说明:对数组{13,8,15,9,5,12,11}按从小到大进行排序。
图1 归并排序示意图
两个子数组进行合并
从上图可以看出,归并排序其中一个很重要的步骤是对已经排好序的子数组进行合并。以一个实例来说明合并的步骤:
C++源码
先给出两个有序子数组合并的代码:
1 void Merge(int array[],int p,int q,int r){ 2 int *temp1 = new int[q-p+1]; 3 int *temp2 = new int[r-q]; 4 for(int i=p;i<=q;i++){ 5 temp1[i-p]=array[i]; 6 } 7 for(int i=q+1;i<=r;i++){ 8 temp2[i-q-1]=array[i]; 9 } 10 int k=0; 11 int z=0; 12 for(int i=p;i<=r;i++){ 13 if((temp1[k]<temp2[z]&&k<q-p+1)||z>=r-q){ 14 array[i]=temp1[k]; 15 k++; 16 } 17 else{ 18 array[i]=temp2[z]; 19 z++; 20 } 21 } 22 }
归并排序划分合并其实是一个递归的过程,原始数组划分为两个子数组,两个子数组再细分成各自的子数组,直到子数组只剩下一个或者两个元素为止。最后将子数组逐步进行合并得出最后已排序的数组。
1 void MergeSort(int array[],int p,int q,int r){ 2 if(r-p==1){ 3 if(array[p]>array[r]){ 4 swap(array,p,r); 5 } 6 return; 7 } 8 if(r-p==0){ 9 return; 10 } 11 int t=floor((p+q)/2); 12 int t1 =floor((q+1+r)/2); 13 MergeSort(array,p,floor((p+q)/2),q); 14 MergeSort(array,q+1,floor((q+1+r)/2),r); 15 Merge(array,p,q,r); 16 }
所有源代码:
1 #include "stdafx.h" 2 #include <iostream> 3 using namespace std; 4 5 //两个位置的数据互换 6 void swap(int array[],int num1,int num2){ 7 int temp = array[num1]; 8 array[num1]=array[num2]; 9 array[num2]=temp; 10 } 11 12 //合并有序的两个序列 13 void Merge(int array[],int p,int q,int r){ 14 int *temp1 = new int[q-p+1]; 15 int *temp2 = new int[r-q]; 16 for(int i=p;i<=q;i++){ 17 temp1[i-p]=array[i]; 18 } 19 for(int i=q+1;i<=r;i++){ 20 temp2[i-q-1]=array[i]; 21 } 22 int k=0; 23 int z=0; 24 for(int i=p;i<=r;i++){ 25 if((temp1[k]<temp2[z]&&k<q-p+1)||z>=r-q){ 26 array[i]=temp1[k]; 27 k++; 28 } 29 else{ 30 array[i]=temp2[z]; 31 z++; 32 } 33 } 34 } 35 36 //归并排序 37 void MergeSort(int array[],int p,int q,int r){ 38 if(r-p==1){ 39 if(array[p]>array[r]){ 40 swap(array,p,r); 41 } 42 return; 43 } 44 if(r-p==0){ 45 return; 46 } 47 int t=floor((p+q)/2); 48 int t1 =floor((q+1+r)/2); 49 MergeSort(array,p,floor((p+q)/2),q); 50 MergeSort(array,q+1,floor((q+1+r)/2),r); 51 Merge(array,p,q,r); 52 } 53 54 int main(int argc, _TCHAR* argv[]) 55 { 56 int temp[]={6,10,4,7,15,12,8,11,9,5}; 57 MergeSort(temp,0,4,9); 58 return 0; 59 }