#include<iostream>
#include<math.h>
using namespace std;
//二路归并:将两个有序序列合并为一个有序序列的过程称为二路归并
//归并排序算法的关键是“合并”两个已排序序列
void merge(int arr[],int begin,int middle,int end){
int n1=middle-begin+1;//n1:子数组arr[begin,middle]的长度
int n2=end-middle;//n2:子数组arr[middle+1,tail]的长度
int i,j,k;
int *L=(int*)malloc(sizeof(int)*n1);//创建长度为n1的数组L
int *R=(int*)malloc(sizeof(int)*n2);//创建长度为n2的数组R
for(i=0;i<n1;i++)//将子数组arr[begin,middle]复制到L[0,n1-1]
{
L[i]=arr[begin+i];
}
for(j=0;j<n2;j++)//将子数组arr[middle+1,tail]复制到R[0,n2-1]
{
R[j]=arr[middle+1+j];
}
i=0;j=0;k=begin;
while(i<n1&&j<n2)
{
if ( L[i] < R[j] )//选取两个数组L[]和R[]中较小的复制到arr[]
{
arr[k++] = L[i++];
}
else
{
arr[k++] = R[j++];
}
}
while(i<n1)
{
arr[k++]=L[i++];
}
while(j<n2)
{
arr[k++]=R[j++];
}
}
void merge_sort(int arr[],int head,int tail){
int middle;
if(head<tail)//若head>=tail,则该数组最多有一个元素,所以已经排好序
{
middle=floor((head+tail)/2);//向下取整
merge_sort(arr,head,middle);
merge_sort(arr,middle+1,tail);
merge(arr,head,middle,tail);
}
}
int main ()
{
int arr[8] = { 5, 2, 4, 7, 1, 3, 2, 6 };
int i = 0;
merge_sort ( arr, 0, 7 );
for ( i = 0; i < 8; i++ )
{
printf ( "%d ", arr[i]);
}
return 0;
}
时间复杂度:
当n=2^k时,可得
T(n)=2(2T(n/4)+n/2)+n
=4T(n/4)+2n
=4(2T(n/8)+n/4)+2n ……
=2^kT(1)+kn =n+nlog2^n
如果2^k<n<2^k+1,有T(n)≤T(2^k+1),有T(n)=O(nlog2n)