mergesort的时间复杂度是恒定的

时间:2020-05-19 10:39:10

标签: c sorting time-complexity array-algorithms

我想尝试执行C实现,但结果很奇怪,因为在谈到mergesort算法时,给定数组的长度(即使其元素由于rand()而成为伪随机的)。每次运行结束时,复杂度实际上都是相同的。我知道,试图以这种方式理解“问题”并不容易,所以这是我从互联网上编写/复制的代码:

#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#define DIM 1000000

void merge(int*, int, int, int);
void mergesort(int*, int, int);
int complexity=0; //Complexity is the variable that counts how many times the program goes through the relevant cycles

int main(int argc, char *argv[]){
  int v[DIM], i;
  time_t t;
  srand((unsigned)time(&t));
  for(i=0; i<DIM; i++){
    v[i]=rand()%100;
    printf("%d\n", v[i]);
  }
  mergesort(v, 0, DIM-1);
  for(i=0; i<DIM; i++)
    printf("%d\t", v[i]);
  printf("\n");
  printf("iterations: %d\n", complexity);
  return 0;
}

void mergesort(int v[], int lo, int hi){
  int mid;
  if(lo<hi){
    mid=(lo+hi)/2;
    mergesort(v, lo, mid);
    mergesort(v, mid+1, hi);
    merge(v, lo, mid, hi);
  }
  return;
}

//This implementation is not actually mine, I got it from a site because I couldn't figure out why mine wouldn't run and order the input
void merge(int v[], int p, int q, int r) {
  int n1, n2, i, j, k, *L, *M;
  n1 = q - p + 1;
  n2 = r - q;
  //creation and initialization of the left and right vectors
  L=(int*)malloc(n1*sizeof(int));
  M=(int*)malloc(n2*sizeof(int));
  for (i = 0; i < n1; i++){
    L[i] = v[p + i];
    complexity++;
  }
  for (j = 0; j < n2; j++){
    M[j] = v[q + 1 + j];
    complexity++;
  }
  //merging section
  i = 0;
  j = 0;
  k = p;
  while (i < n1 && j < n2) {
    if (L[i] <= M[j]) {
      v[k] = L[i];
      i++;
      complexity++;
    } else {
      v[k] = M[j];
      j++;
      complexity++;
    }
    k++;
  }
  //from what I understood this should be the section where what is left out gets copied inside        the remaining spots
  while (i < n1) {
    v[k] = L[i];
    i++;
    k++;
    complexity++;
  }
  while (j < n2) {
    v[k] = M[j];
    j++;
    k++;
    complexity++;
  }
  return;
}

我也会将图像留给我在这里进行各种排序算法的几次试验

Data for the Mergesort trials are down in the corner, as you can see there is just a row of data simply because the complexity was constant and independent from the actual content of the vector

这是一个问题:让计算时间复杂度的变量恒定是正常的吗?我最初的想法是由于计数器的错误实现,尽管我对算法的了解不强,但我不知道如何证明它。 如果那最终是正确的答案,您可以指导我实现计数器的一种实现(不是太复杂,但仍然可以起作用)以更精确地评​​估时间复杂度吗?

编辑:我上传的excel屏幕截图的A到I列对应于随机生成的数组的长度,值分别为:100、500、1000、5000、10000、50000、1000000。

1 个答案:

答案 0 :(得分:1)

无论数组的内容如何,​​merge函数都会使complexity递增2(r-p+1)。由于merge函数是代码中唯一依赖于数组内容的部分,因此这表明complexity变量总体上增加了固定次数。

以下是merge函数为何将complexity增加2(r-p+1)的示意图:

此块将其递增n1

for (i = 0; i < n1; i++){
    L[i] = v[p + i];
    complexity++;
}

n2阻止:

for (j = 0; j < n2; j++){
    M[j] = v[q + 1 + j];
    complexity++;
}

在其余代码中,ij从0开始,并且在每一步,ij都增加1,而complexity增加。函数返回时,in1,而jn2,因此这会向n1+n2添加另一个complexity

由于n1 = q-p+1n2 = r-q,总体上merge函数使复杂度增加了2*n1 + 2*n2 = 2(q-p+1+r-q) = 2(r-p+1)