1. 程式人生 > >歸併排序—演算法導論

歸併排序—演算法導論

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