#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
#include <time.h>
#define MAX_ELEMENT_IN_ARRAY 1000000001
int
cmpfunc (
const
void
* a,
const
void
* b)
{
return
( *(
int
*)a - *(
int
*)b );
}
int
* generate_random_array(
int
n)
{
srand
(
time
(NULL));
int
*a =
malloc
(
sizeof
(
int
) * n), i;
for
(i = 0; i < n; ++i)
a[i] =
rand
() % MAX_ELEMENT_IN_ARRAY;
return
a;
}
int
* copy_array(
int
a[],
int
n)
{
int
*arr =
malloc
(
sizeof
(
int
) * n);
int
i;
for
(i = 0; i < n ;++i)
arr[i] = a[i];
return
arr;
}
void
insertion_sort_asc(
int
a[],
int
start,
int
end)
{
int
i;
for
(i = start + 1; i <= end ; ++i)
{
int
key = a[i];
int
j = i - 1;
while
(j >= start && a[j] > key)
{
a[j + 1] = a[j];
--j;
}
a[j + 1] = key;
}
}
void
merge(
int
a[],
int
start,
int
end,
int
mid)
{
int
i = start, j = mid + 1, k = 0;
int
*aux =
malloc
(
sizeof
(
int
) * (end - start + 1));
while
(i <= mid && j <= end)
{
if
(a[i] <= a[j])
aux[k++] = a[i++];
else
aux[k++] = a[j++];
}
while
(i <= mid)
aux[k++] = a[i++];
while
(j <= end)
aux[k++] = a[j++];
j = 0;
for
(i = start;i <= end;++i)
a[i] = aux[j++];
free
(aux);
}
void
_merge_sort(
int
a[],
int
start,
int
end)
{
if
(start < end)
{
int
mid = start + (end - start) / 2;
_merge_sort(a,start,mid);
_merge_sort(a,mid + 1,end);
merge(a,start,end,mid);
}
}
void
merge_sort(
int
a[],
int
n)
{
return
_merge_sort(a,0,n - 1);
}
void
insertion_and_merge_sort_combine(
int
a[],
int
start,
int
end,
int
k)
{
if
(start < end)
{
int
size = end - start + 1;
if
(size <= k)
{
return
insertion_sort_asc(a,start,end);
}
int
mid = start + (end - start) / 2;
insertion_and_merge_sort_combine(a,start,mid,k);
insertion_and_merge_sort_combine(a,mid + 1,end,k);
merge(a,start,end,mid);
}
}
void
test_sorting_runtimes(
int
size,
int
num_of_times)
{
int
number_of_times = num_of_times;
int
t = number_of_times;
int
n = size;
double
insertion_sort_time = 0, merge_sort_time = 0;
double
merge_sort_and_insertion_sort_mix_time = 0, qsort_time = 0;
while
(t--)
{
clock_t
start, end;
int
*a = generate_random_array(n);
int
*b = copy_array(a,n);
start =
clock
();
insertion_sort_asc(b,0,n-1);
end =
clock
();
insertion_sort_time += ((
double
) (end - start)) / CLOCKS_PER_SEC;
free
(b);
int
*c = copy_array(a,n);
start =
clock
();
merge_sort(c,n);
end =
clock
();
merge_sort_time += ((
double
) (end - start)) / CLOCKS_PER_SEC;
free
(c);
int
*d = copy_array(a,n);
start =
clock
();
insertion_and_merge_sort_combine(d,0,n-1,40);
end =
clock
();
merge_sort_and_insertion_sort_mix_time+=((
double
) (end - start))/CLOCKS_PER_SEC;
free
(d);
start =
clock
();
qsort
(a,n,
sizeof
(
int
),cmpfunc);
end =
clock
();
qsort_time += ((
double
) (end - start)) / CLOCKS_PER_SEC;
free
(a);
}
insertion_sort_time /= number_of_times;
merge_sort_time /= number_of_times;
merge_sort_and_insertion_sort_mix_time /= number_of_times;
qsort_time /= number_of_times;
printf
(
"\nTime taken to sort:\n"
"%-35s %f\n"
"%-35s %f\n"
"%-35s %f\n"
"%-35s %f\n\n"
,
"(i)Insertion sort: "
,
insertion_sort_time,
"(ii)Merge sort: "
,
merge_sort_time,
"(iii)Insertion-mergesort-hybrid: "
,
merge_sort_and_insertion_sort_mix_time,
"(iv)Qsort library function: "
,
qsort_time);
}
int
main(
int
argc,
char
const
*argv[])
{
int
t;
scanf
(
"%d"
, &t);
while
(t--)
{
int
size, num_of_times;
scanf
(
"%d %d"
, &size, &num_of_times);
test_sorting_runtimes(size,num_of_times);
}
return
0;
}