引言
只要设计到数据,就会涉及到数据的排序问题,比如给你随机给你五个整数 3,1,5,2,4 。让你从小到大进行排序,那我们该怎样才是实现对这些整数的排序呢 ?
答案是多种多样的,比如用插入排序、希尔排序、堆排序、归并排序、快速排序等等,这些排序方法都可以实现对整数排序,而这篇文章要讲的就是归并排序
本文将从以下几个问题对归并排序进行分析和讲解:
- 什么是归并排序?
- 归并排序的大概过程是什么?
- 怎样用代码实现归并排序?
- 归并排序的代码详解。
什么是归并排序?
下面看百度百科对归并排序的定义:
归并排序(MERGE-SORT)是建立在归并操作上的一种有效的排序算法,该算法是采用分治法(Divide and Conquer)的一个非常典型的应用。将已有序的子序列合并,得到完全有序的序列;即先使每个子序列有序,再使子序列段间有序。若将两个有序表合并成一个有序表,称为二路归并。归并排序是一种稳定的排序方法。
简单理解:归并排序一个分两大部,第一步分,第二步合。
下面先看一个动图:
归并排序的大概过程是什么?
我们用归并排序讲一个例子来说明,要排序的数组为3,1,5,2,4.
归并排序第一步:分
分采取一份为二的方法(所以这个归并排序又叫二路归并排序)
mid=(first+last)/2(first是最左边,last是最右边),采取前面的公式,分为【first,mid】和【mid+1,last】
如上图所示,直到分成一个一个的数,分的话可以采取递归调用的方法。
再看第二大步:合
合是指把两个数组合成一个数组,而且合成之后数组是有序的。
合成方法:在合成过程中需要一个临时数组来存合成的结果。可以定义两个变量 i 和 j 分别指向两个数组的第一个元素,比较他俩谁小。就是那个对应的元素放到临时数组里面,指向数组的变量后移。只要其中一个变量走到头位置。
如果是其中一个走到头了,但是另一个还未到头,这时候就需要把数组剩余的元素放到临时数组里面。
上面说的是把两个数组合二为一,但是两个数组其实是一个数组中两块不同的部分(用下标区分的),等上面合成结束,就把临时数组放到原数组里面,下面看合代码。
//将两个有序数列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 m=mid , n=last; int k=0; while(i<=m&&j<=n) { if(a[i]<=a[j]) temp[k++]=a[i++]; else temp[k++]=a[j++]; } while(i<=m) temp[k++]=a[i++]; while(j<=n) temp[k++]=a[j++]; for(i=0;i<k;i++) a[first+i]=temp[i]; }
怎样用代码实现归并排序?
下面看完整的代码
#include<iostream> using namespace std; //将两个有序数列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 m=mid , n=last; int k=0; while(i<=m&&j<=n) { if(a[i]<=a[j]) temp[k++]=a[i++]; else temp[k++]=a[j++]; } while(i<=m) temp[k++]=a[i++]; while(j<=n) temp[k++]=a[j++]; for(i=0;i<k;i++) a[first+i]=temp[i]; } //归并排序函数 稳定 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); } } //输出数组的值 void printf(int arr[],int len) { for(int i=0;i<len;i++) cout<<arr[i]<<" "; cout<<endl; } int main() { //要排序的数组 int arr[]={3, 44,38, 5,47,15,36,26,27,2 ,46,4 ,19,50,48}; int len=15;//要排序的数组长度 int temp[1]; //排序 MergeSort(arr,0,len-1,temp); //输出 printf(arr,len); return 0; }
运行结果:
归并排序代码详解
- 第一步分,首先要知道怎样分,采取的是递归调用,记得注意递归的结束条件
- 第二步合,把两个小数组合成一个大数组,合的过程应该是啥,一定要清楚
本文参考以及引用: