Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/typo3/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C mergesort的时间复杂性是恒定的_C_Sorting_Time Complexity_Array Algorithms - Fatal编程技术网

C mergesort的时间复杂性是恒定的

C mergesort的时间复杂性是恒定的,c,sorting,time-complexity,array-algorithms,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);

我想尝试做一个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;
}
我将留下一张图片,让我在这里对各种排序算法进行一些试验

问题是:将计算时间复杂性的变量设置为常量是否正常?我最初的想法是,这是由于计数器的实现不好,我不知道如何证明这一点,只是因为我对算法的知识不是很强。 如果这最终是正确的答案,您能否指导我实现一个不太复杂但仍具有计数器功能的实现,以便更精确地评估时间复杂性


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

无论数组的内容如何,合并函数都会将复杂性增加2r-p+1。由于merge函数是代码中唯一依赖于数组内容的部分,这表明复杂度变量总体上增加了固定的次数

下面是合并函数将复杂性增加2r-p+1的原因:

此块将其递增n1:

在剩下的代码中,i和j从0开始,在每一步,i或j都会增加1,复杂性也会增加。当函数返回时,i是n1,j是n2,因此这又增加了n1+n2的复杂性


由于n1=q-p+1和n2=r-q,合并函数总体上增加了复杂度2*n1+2*n2=2q-p+1+r-q=2r-p+1。

你的意思是迭代计数器复杂度对于给定的输入大小有一个常量值,与输入数据的实际值无关吗?@Hulk,正是这样。例如,给定100个元素的向量,输出总是1344个循环的迭代,或者对于500个元素的向量,输出是8976个循环,与向量内的实际值无关。我忘了在图像中包括输入的长度,它们是:1005001000500010000 50000,因此,在理论层面上,我实现这个计数器来跟踪迭代次数是正确的,我在web上获取的合并函数和mergesort心态通常不依赖于输入向量中的实际值;就像quicksort和insertionsort一样,在我的测试过程中,这两种方法都使相同输入长度的循环数略有变化。这有什么意义吗?
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++;
}