【问题标题】:Merge sort with n extra space合并排序与 n 额外空间
【发布时间】:2014-03-08 23:56:50
【问题描述】:

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

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]);
}

【问题讨论】:

  • 这段代码很难理解——它没有 cmets,而且几乎每个变量都只有一个字母的长度。此外,缩进关闭,代码似乎没有关闭括号。您的问题的答案是“可能”,但如果您的算法过于模糊和不完整而无法理解,我们将无法为您提供帮助!
  • 您错过了合并床的删除。合并完成并且您已复制回原始序列后,对临时存储的需求也是如此。我不认为您至少可以为此使用std::vector&lt;&gt;? (很明显你不能使用std::mergestd::inplace_merge 如果这是用于学术界)。而且我还没有审查实际的算法,所以如果它错了,那本身就是另一个问题。
  • 哦对了,代码末尾应该有一个删除。是的,这是给学校的,所以我不能只使用 std::vector 或 std::merge。该算法运行良好,可以完美地对数组进行排序。
  • 啊。太糟糕了。 Sok,但仅供参考,您也不需要两个分区索引。您的 mergesort_normal 函数可以只接受两个参数,一个基地址和一个长度。指针算法可以进行分区。想一想。
  • 我不允许更改函数的参数

标签: c++ algorithm sorting merge


【解决方案1】:

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

由于您的教授不会让您传递任何额外的参数,您将不得不做一些小技巧才能使用辅助数组 - 我们将在末尾使用尽可能多的空间我们传入数组,就像传入数组本身一样。请注意,这需要您传入一个数组,该数组的长度是正常的两倍,一半是垃圾(我们只需要空间)——而且还需要一些额外的工作来确保您知道辅助数组从哪里开始。

我会尽量避免给你确切的代码,因为这是家庭作业——但我使用的想法(我刚刚在我的电脑上工作)是保留一个名为 helper 的全局变量,它是指向“数组的结尾”(或辅助数组的开头)。然后,当您进入 mergesort() 调用时,检查它是否已初始化 - 如果没有,请将其指向辅助数组的开头。除此之外,您的代码可以保持基本相同 - 但不是在每个合并函数的开头创建一个新数组 helper[],而是使用全局数组。

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

【讨论】:

    猜你喜欢
    • 2017-01-08
    • 1970-01-01
    • 1970-01-01
    • 2011-01-18
    • 2020-03-25
    • 1970-01-01
    • 2015-12-16
    • 1970-01-01
    • 2011-02-27
    相关资源
    最近更新 更多