关于我的QuickSort算法的困惑& Mergesort算法

时间:2015-04-18 22:30:28

标签: objective-c time-complexity quicksort mergesort

我目前正在进行实证研究,以评估快速排序和合并算法的运行时复杂性。为此,我运行一个随机数生成器,它存储我在二进制文件中指定的任何数量的数字。这些数字的范围是1-1,000,000.I然后从100,000个数字开始运行每个算法的测试,每次增加50,000,直到最后一次运行排序1,000,000个数字。每个20个测试。我已成功完成每个算法,但我的结果有点令人费解。这是显示我的结果的图表。

enter image description here

据我所知,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功能更有效的建议。谢谢!

1 个答案:

答案 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 ;
}