当前位置: 首页 > 知识库问答 >
问题:

在进行合并排序时是否有必要将索引作为参数传递?

沈良策
2023-03-14

我在网上看到了许多mergesort的实现,比如https://www.geeksforgeeks.org/merge-sort/传入参数l、m和r,以了解子数组的开始和结束位置。我想知道,如果我们复制子数组并将其传入,运行时和空间复杂性是否会保持不变。建议的代码示例如下:

class Solution {

    //mergeSort implementation
    public int[] sortArray(int[] nums) {

        if (nums.length == 1) {
            return nums;
        }

        int arrayLength = nums.length;

        // make copies instead of passing indices
        int[] left = Arrays.copyOfRange(nums, 0, arrayLength/2);
        int[] right = Arrays.copyOfRange(nums, arrayLength/2, arrayLength);

        left = sortArray(left);
        right = sortArray(right);

        return merge(left, right);

    }

    public int[] merge(int[] left,int[] right) {

        int[] merged = new int[left.length + right.length];

        int mergedCounter = 0;
        int i = 0; //leftCounter
        int j = 0; //rightCounter
        while (mergedCounter != left.length + right.length) {
            if (i == left.length) {
                merged[mergedCounter] = right[j];
                mergedCounter++;
                j++;
            } else if (j == right.length) {
                merged[mergedCounter] = left[i];
                mergedCounter++;
                i++;
            } else {
                if (left[i] <= right[j]) {
                    merged[mergedCounter] = left[i];
                    mergedCounter++;
                    i++;
                } else {
                    merged[mergedCounter] = right[j];
                    mergedCounter++;
                    j++;
                }
            }
        }

        return merged;

    }

}

我相信运行复杂性并没有增加,因为创建一个副本所需的运行时间与通过new int[n]初始化一个n长度的新数组所需的运行时间相同。问题的这一部分还包括一个O(n)merge子函数,所以这无关紧要。

我也相信空间的复杂性保持不变。当我们在递归调用中创建两个临时子数组时,将在合并步骤中创建与使用指向l、m和r的指针的在线解决方案中指定的相同数量的空间。

我的思考过程是有效的,还是我错过了什么?

共有1个答案

鲁弘厚
2023-03-14

任何额外的复制操作都会增加运行时间。复制子阵列将增加常量的空间需求,但由于“复杂性”忽略常量和/或低阶项,空间“复杂性”将保持不变。

大多数库使用自下而上合并排序的一些变体,其中索引(或指针)会动态更新,而不是通过递归传递,并且通常保存在基于编译器优化的寄存器中。自上而下的合并排序主要用作学习练习。

通过基于自下而上合并排序的合并过程或自上而下合并排序的递归级别更改合并方向,可以最小化复制操作。

对于C/C,传递数组和索引的替代方法是传递指针或迭代器,将每次调用所需的参数数减少1个参数。

 类似资料:
  • 问题内容: 如果排序列上有索引,排序是否使用mysql索引?索引还用于其他什么用途? 它对列的组合索引和单独索引有什么区别? 问题答案: 是的,当按排序列排序时,MySQL使用索引对信息进行排序。 另外,如果在添加到 SELECT 子句的所有列中都有索引,则MySQL不会从表本身加载数据,而是从索引加载数据(更快)。 合并和单独的索引之间的区别是,MySQL不能使用超过 一个 每次查询索引,因此,

  • 问题内容: 我们的MySql表有2500万行 以下是表中的列 以上我们在c_id,c_name,s_id,l_type,域列上具有正常索引 我打算在域,l_time,l_type列上添加复合索引。因此,现在我可以删除域上的单个索引了吗? 谢谢 问题答案: 复合索引的任何前缀也将单独用作索引。因此,如果您有一个复合索引,则相当于在和上都有索引。无需分别将这些索引分开,它们将是多余的并且浪费空间。 因

  • 我想用Javascript实现合并排序作为一种学习经验。我有mergeSort(unsortedArray)函数,它接受一个未经排序的数组,并使用合并排序策略对其进行排序。mergeSort()调用merge(leftArray,rightArray),后者将两个数组合并在一起,得到一个数组。 我认为问题出在merge()函数上。在数组[8,8,7,5,4,6,3,2,1,5,9,8,7,6,5,

  • 我基本上理解了包含数组、低整数和高整数的递归合并排序函数。然而,我很好奇地试图编写一个只包含数组长度的递归合并排序函数。签名是:这比我想象的要困难得多。 我将在下面发布代码,但我的函数(我认为)只是为每次调用merge_sort()拆分数组的前半部分,本质上不涉及数组的后半部分(我认为也是如此)。 我遇到的另一个问题是,当将所有内容从辅助数组复制回原始数组(使用for循环)时,我不确定使用什么作为

  • 我一直在研究一种合并排序算法,我想最终用它对字符串数组进行排序。 理论上,我对一个包含ID的数组进行排序,我想按照与字符串主数组相同的顺序对其进行排序,然后对ID数组进行排序,并对字符串数组执行相同的操作,理论上对它们进行相同的排序。 例如,ID值的数组可以是[1,2,3,4,5],而主数组看起来像["Name,1","Name,2"]... 当我在不包含任何第二个数组部分的情况下运行算法时,它工

  • 问题内容: 我正在尝试排序(减少)整数数组,但要跟踪原始索引。 我的意思是,例如,如果我有这个数组: 使用Arrays.sort(b,Collections.reverseOrder())之后变成(我使用Arrays.sort,因为在此示例中b的长度仅为5,但是在我的问题中b的长度可能是1 <b.length <70 但我想以某种方式拥有原始索引,我的意思是知道 我不知道我的问题是否明确,请向我询