【问题标题】:Merge two sorted arrays with recursion without 3nd array使用没有第三个数组的递归合并两个排序数组
【发布时间】:2022-01-16 08:57:48
【问题描述】:

我是一年级计算机科学专业的学生。 我被赋予了递归任务。 我需要编写一个递归函数来获取两个数组,它们是它们的物理大小(非负数),并对数组进行排序并以排序方式将它们放入第二个数组中,而无需设置数组来寻求帮助。大概第二个数组的大小就足够了。我无法编写适合我的代码,我希望你能帮助我。

【问题讨论】:

  • 数组是否已排序?因为在标题中你写了“合并两个排序的数组”,但在描述中你写的函数应该对数组进行排序。
  • "得到两个数组" 怎么样?函数的接口是什么?它在哪里可以访问它们? “它们是它们的物理大小”尚不清楚。界面是否提供这些尺寸? “想必第二个数组的大小就足够了。” 好。但是你需要三个大小,数组 1,数组 2 中要排序的条目以及数组的总大小。或者保证数组 2 可以取所有,并且仍然是要排序的条目的数量。您需要提供minimal reproducible example 来定义接口。然后,您可以获得实施方面的帮助。考虑引用整个家庭作业。
  • 你仍然应该展示你自己的努力。否则...
  • 所有“不知道如何开始”问题的答案是:“阅读、查找工作示例、尝试、修复、重做”。 IE。阅读一些教科书或教程,找到一个 HelloWorld 或示例代码,尝试朝着你的目标小步改变它,测试,调试;然后尝试下一次迭代。根据How to Ask 并可能使用此处描述的折衷方案:meta.stackoverflow.com/questions/334822/…跨度>

标签: arrays c sorting recursion mergesort


【解决方案1】:

所以你有两个排序数组,我们假设第二个数组分配了额外的空间来保存合并后的数组。

这是记忆中的样子:

array0, length 4
+-------+
|a|b|d|h|
+0-1-2-3+

array1, length 3
+-------------+
|b|c|e| | | | |
+0-1-2-3-4-5-6+

多余的空间在array1的存储空间的末尾。

合并数组后,array1 的索引 6 处的值是多少?由于索引 6 将是合并数组中的最后一个元素,因此它将是任一输入数组的最大元素。由于输入数组已经排序,它将是array0 的最后一个元素或array1 的最后一个元素。让我们比较它们并将较大的元素复制到索引 6。由于 h 大于 e,我们将 h 复制到索引 6。由于我们现在将 array0 的最后一个元素放在其最终位置,我们可以假装array0 现在长度为 3。

array0, length 3
+-------+
|a|b|d| |
+0-1-2-3+

array1, length 3
+-------------+
|b|c|e| | | |h|
+0-1-2-3-4-5-6+

现在我们对 array1 的索引 5 再次执行相同的操作。我们比较(缩短的)array0array1 的最后一个元素。由于e 大于d,我们将e 复制到索引5 并将array1 的长度减少1:

array0, length 3
+-------+
|a|b|d| |
+0-1-2-3+

array1, length 2
+-------------+
|b|c| | | |e|h|
+0-1-2-3-4-5-6+

重复直到输入数组被缩短到长度为 0,array1 的存储将被最终合并的数组填充。

【讨论】:

    【解决方案2】:

    这是之前建议的工作代码。
    如果您知道如何使其成为二进制文件,我想在这里提出您的建议。

    void combineArrays(int sortedArr1[], int size1,
        int sortedArr2[], int size2)
    {
        int combinedSizes = size1 + size2;
        if (size1 == 0);
        else if (sortedArr1[size1 - 1] > sortedArr2[size2 - 1])
        {
            sortedArr2[size2+size1-1] = sortedArr1[size1 - 1];
            combineArrays(sortedArr1, size1 - 1, sortedArr2, size2);
        }
        else//sortedArr1[size1 - 1] < sortedArr2[size2 - 1]
        {
            sortedArr2[size2 + size1 - 1] = sortedArr2[size2 - 1];
            combineArrays(sortedArr1, size1, sortedArr2, size2 - 1);
        }
    }
    

    【讨论】:

    • combinedSizes 未使用。 if (size1 == 0); else ... 不优雅。
    • 如果size2 == 0 怎么办? if (sortedArr1[size1 - 1] &gt; sortedArr2[size2 - 1]) 会有未定义的行为。
    【解决方案3】:

    假设数组不重叠,您可以从最高索引开始合并已排序的数组:

    void mergeArrays(const int * restrict a1, size_t n1,
                     int * restrict a2, size_t n2)
    {
        for (size_t k = n1 + n2; n1 > 0;) {
            if (n2 == 0 || a1[n1 - 1] > a2[n2 - 1]) {
                a2[--k] = a1[--n1];
            } else {
                a2[--k] = a2[--n2];
            }
        }
    }
    

    这可以简化为:

    void mergeArrays(const int * restrict a1, size_t n1,
                     int * restrict a2, size_t n2)
    {
        for (size_t k = n1 + n2; n1 > 0;)
            a2[--k] = (n2 == 0 || a1[n1 - 1] > a2[n2 - 1]) ? a1[--n1] : a2[--n2];
    }
    

    如果需要使用递归,将循环改为递归调用:

    void mergeArrays(const int * restrict a1, size_t n1,
                     int * restrict a2, size_t n2)
    {
        if (n1 > 0) {
            if (n2 == 0 || a1[n1 - 1] > a2[n2 - 1]) {
                a2[n1 + n2 - 1] = a1[n1 - 1];
                mergeArrays(a1, n1 - 1, a2, n2);
            } else {
                a2[n1 + n2 - 1] = a2[n2 - 1];
                mergeArrays(a1, n1, a2, n2 - 1);
            }
        }
    }
    

    【讨论】:

      猜你喜欢
      • 2019-09-09
      • 1970-01-01
      • 2015-06-05
      • 2017-02-20
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-02-17
      相关资源
      最近更新 更多