我目前正在进行实证研究,以评估快速排序和合并算法的运行时复杂性。为此,我运行一个随机数生成器,它存储我在二进制文件中指定的任何数量的数字。这些数字的范围是1-1,000,000.I然后从100,000个数字开始运行每个算法的测试,每次增加50,000,直到最后一次运行排序1,000,000个数字。每个20个测试。我已成功完成每个算法,但我的结果有点令人费解。这是显示我的结果的图表。
据我所知,quicksort的O(n2)时间最差,但通常是O(n·lg(n))时间。 Mergesort具有Θ(n·lg(n))时间。
另外我想注意,当我启动计时器时,我只使用了time.h中的clock(),并计算了经过的时间。在调用我的排序功能之前,我启动了一行代码。
我不明白的是,我的图表显示mergesort总是加倍的时间,与快速排序相比,排序数字的时间增加了三倍。
我唯一想到的是,对于我的mergesort算法,每次将数组分成两半时,我都会使用malloc为每一半创建一个新的整数数组。当然,这意味着考虑到我正在排序的数字大小,会对malloc进行大量调用。
int* mergeSort(int* nums, int size){
int* left;
int* right;
int middle = size/2;
if(size <= 1)
return nums;
split(nums, size, &left, &right, middle);
//I dont understand why the code below wouldnt work in place of the split()
//when i run it, in main, nothing gets printed out. I guess i lose my pointer to the beginning of my array.
//left = nums;
//right = nums+middle;
left = mergeSort(left, middle);
right = mergeSort(right, size - middle);
merge(nums,left,right,middle,size - middle);
free(left);
free(right);
return nums;
}
void split(int* nums, int size, int** left, int** right, int middle){
int *lft = (int*) malloc ((sizeof(int) * middle));
int *rght = (int*) malloc ((sizeof(int) * size - middle));
int mid = middle;
int upMid = size - middle;
int i;
for(i=0; i < mid; i++)
lft[i] = nums[i];
for(i=0; i < upMid; i++)
rght[i] = nums[i+middle];
*left = lft;
*right = rght;
}
void merge(int* num, int* left, int* right, int sizeLeft, int sizeRight){
int i,j,k,n;
i=j=k=0;
n=sizeLeft + sizeRight;
while(k < n){
if(i< sizeLeft){
if(j<sizeRight){
insert(num,left,right,&i,&j,&k);
}
else{
append(num, left, sizeLeft, &i, &k);
}
}
else{
append(num,right,sizeRight,&j,&k);
}
}
}
void insert(int* num, int* left, int* right, int* i, int* j, int* k){
/*int i,j,k,n;*/
if(left[*i]<right[*j]){
num[*k] = left[*i];
(*i)++;
}
else{
num[*k] = right[*j];
(*j)++;
}
(*k)++;
}
void append(int* num, int* half, int sizeHalf, int* i, int* k){
while(*i < sizeHalf){
num[*k]= half[*i];
(*i)++; (*k)++;
}
}
我非常感谢我对这个问题的任何反馈,以及任何有关使我的mergesort功能更有效的建议。谢谢!
答案 0 :(得分:0)
我已经实现了合并排序算法,你可以看看。我在mergeSort
的开头malloc一个bak数组,然后每个合并都使用它。
#include <string>
#include <stdlib.h>
void _mergeSort(int *array, int *bakArray, int len) ;
void mergeSort(int *array, int len)
{
int *bak = (int *)malloc(sizeof(int)*len) ;
_mergeSort(array, bak, len) ;
free(bak) ;
}
void _mergeSort(int *array, int *bakArray, int len)
{
if (len >= 2) {
int leftLen = len/2 ;
_mergeSort(array, bakArray, leftLen) ;
_mergeSort(array+leftLen, bakArray, len-leftLen) ;
int *pa = array ;
int *pb = array+leftLen ;
int aIndex = 0 ;
int bIndex = 0 ;
while (aIndex < leftLen && bIndex < len-leftLen) {
int a = pa[aIndex] ;
int b = pb[bIndex] ;
if (a < b) {
bakArray[aIndex+bIndex] = a ;
++aIndex ;
} else if (a == b) {
bakArray[aIndex+bIndex] = a ;
bakArray[aIndex+bIndex+1] = a ;
++aIndex ;
++bIndex ;
} else {
bakArray[aIndex+bIndex] = b ;
++bIndex ;
}
}
if (aIndex < leftLen) {
memcpy(bakArray+aIndex+bIndex, pa+aIndex, sizeof(int)*(leftLen-aIndex)) ;
} else if (bIndex < len-leftLen) {
memcpy(bakArray+aIndex+bIndex, pb+bIndex, sizeof(int)*(len-leftLen-bIndex)) ;
}
memcpy(array, bakArray, sizeof(int)*len) ;
}
}
static const int MaxArraySize = 100 ;
int main()
{
srand(time(NULL)) ;
int array[MaxArraySize] ;
for (int i = 0 ; i < MaxArraySize; ++i) {
array[i] = rand() % 10000 ;
}
mergeSort(array, MaxArraySize) ;
for (int i = 0 ; i < MaxArraySize; ++i) {
printf("%d ", array[i]) ;
}
printf("\n") ;
return 0 ;
}