合并排序与额外的空间

时间:2014-03-08 23:56:50

标签: c++ algorithm sorting merge

我创建了一个Merge排序,效率非常低,空间占用空间很大。每次递归调用都会创建一个新数组。在不影响我的函数参数的情况下,我可以创建一个动态数组,我只需要创建和删除一次吗?

void mergesort_normal(Item *A, int p, int r)
{

    int middle;
     if (p < r) {
      middle = p + (r - p) / 2;
      mergesort_normal(A, p, middle);
      mergesort_normal(A, middle +1, r);
      merge_normal(A, p, middle, r);
    }
  }

void merge_normal  (Item *A, int p, int mid, int r)
{
    Item *helper = new Item[r+1];
    int h = p;
    int i = p;
    int j = mid +1;
    int k = 0;


while((h<=mid)&&(j<=r))
{
    if(lessThan(A[h], A[j]))
    {
        helper[i]=key(A[h]);
        h++;
    }
    else
    {
        helper[i]=key(A[j]);
        j++;
    }
    i++;
}
 if(h>mid)
 {
    for(k=j;k<=r;k++)
    {
        helper[i]=key(A[k]);
        i++;
    }
 }
 else
 {
    for(k=h;k<=mid;k++)
    {
        helper[i]=key(A[k]);
        i++;
    }
 }
 for(k=p;k<=r;k++)
     A[k]=key(helper[k]);
}

1 个答案:

答案 0 :(得分:1)

通常,仅使用n个额外空间的合并排序使用传递到merge()mergesort()函数的辅助数组。然后,不是每次都创建一个新的辅助数组,而只是在当前merge()调用中使用辅助数组中的相同索引 - 这样,所有merge()调用都可以不踩对方的脚趾就做他们的事。

由于你的教授不会让你传递任何额外的参数,你将不得不做一些有点hacky能够使用辅助阵列的东西 - 我们将在末尾使用尽可能多的空间数组我们传入,就像我们为数组本身做的那样。请注意,这需要您传入一个正常的数组两倍,使用垃圾填充一半(我们只需要空间) - 它还需要一些额外的工作来确保您知道辅助数组的起始位置。

我将尽量避免给你提供准确的代码,因为这是作业 - 但我使用的想法(我只是在我的计算机上运行)是保留一个名为helper的全局变量,它是指向“数组的末尾(或辅助数组的开头)。然后,当您进入mergesort()调用时,检查它是否已初始化 - 如果没有,则将其指向辅助数组的开头。除此之外,您的代码可以保持基本相同 - 但不是在每个合并函数的开头创建一个新数组helper[],只需使用全局代码。

如果有人有一个不涉及使用全局变量的解决方案,我会全力以赴 - 但在限制范围内,这是有效的。