归并排序
定义
归并排序(MERGE-SORT)是建立在归并操作上的一种有效的排序算法,该算法是采用分治法(Divide and Conquer)的一个非常典型的应用。将已有序的子序列合并,得到完全有序的序列;即先使每个子序列有序,再使子序列段间有序。若将两个有序表合并成一个有序表,称为二路归并。
原理
第一步:申请空间,使其大小为两个已经排序序列之和,该空间用来存放合并后的序列。
第二步:设定两个指针,最初位置分别为两个已经排序序列的起始位置。
第三步:比较两个指针所指向的元素,选择相对小的元素放入到合并空间,并移动指针到下一位置 重复步骤3直到某一指针超出序列尾。
将另一序列剩下的所有元素直接复制到合并序列尾。
时间复杂度:O(nlogn)
空间复杂度:O(N),归并排序需要一个与原数组相同长度的数组做辅助来排序。
稳定性:归并排序是稳定的排序算法
实现
递归
void mergeArray(int arr[],int first,int mid,int last)
{
int i=first,j=mid+1,m=mid,n=last,k=0,temp[maxn];
while(i<=m&&j<=n)
{
if(arr[i]<=arr[j]) temp[k++]=arr[i++];
else temp[k++]=arr[j++];
}
while(i<=m) temp[k++]=arr[i++];
while(j<=n) temp[k++]=arr[j++];
for(i=0;i<k;i++) arr[first+i]=temp[i];
}
void mySort(int arr[],int first,int last)
{
if(first<last)
{
int mid=(first+last)/2;
mySort(arr,first,mid);
mySort(arr,mid+1,last);
mergeArray(arr,first,mid,last);
}
}
非递归
非递归的思想和ST表类似,妙啊~
void mergeArray(int arr[],int n,int length) { int now=0,top=0,left,right,temp[maxn],k=0; while(now<n) { left=now; right=now+length; while(left<now+length&&right<now+2*length&&left<n&&right<n) { if(arr[left]<=arr[right]) temp[k++]=arr[left++]; else temp[k++]=arr[right++]; } while(left<now+length&&left<n) temp[k++]=arr[left++]; while(right<now+2*length&&right<n) temp[k++]=arr[right++]; now=now+2*length; } for(int i=0;i<n;i++) arr[i]=temp[i]; } void mySort(int arr[],int n) { int length=1; while(length<n) { mergeArray(arr,n,length); length*=2; } }