归并排序—算法导论

#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)

猜你喜欢

转载自blog.csdn.net/qq_40301016/article/details/82780005