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

合并排序:合并函数数组索引零返回多个索引

裴心水
2023-03-14

我想用Javascript实现合并排序作为一种学习经验。我有mergeSort(unsortedArray)函数,它接受一个未经排序的数组,并使用合并排序策略对其进行排序。mergeSort()调用merge(leftArray,rightArray),后者将两个数组合并在一起,得到一个数组。

我认为问题出在merge()函数上。在数组[8,8,7,5,4,6,3,2,1,5,9,8,7,6,5,4,2,3,6,5,4,8]上调用mergeSort时,我得到的结果是:[1,4,2,3,5,5,9,6,7,8,8]。据我所知,问题的根源在于,在merge()函数中,当对leftarray[0]和righttarray[0]进行比较时,righttarray[0]有时返回多个值,而不仅仅是第一个索引。在我的例子中,它是用2,3和5,9来做的。因此,当代码运行时,有时RightArray[0]=2,3,在数组中拼接2,3之后,RightArray[0]=5,9。以下是merge()中发生此问题时的情况:

左胸:[4,5,6,7,8,8]
右胸:[1,2,3,5,9]
结果:[]

左房[4,5,6,7,8,8]
右房[2,3,5,9]
结果:[1]

(索引不正确...数组[0]返回两个值)
leftarray[0]=4
righttarray[0]=2,3

左曲面[5,6,7,8,8]
右曲面[2,3,5,9]
结果[1,4]

(索引不正确...数组[0]返回两个值)
leftarray[0]=5
righttarray[0]=2,3

左曲面[5,6,7,8,8]
右曲面[5,9]
结果[1,4,2,3]

...数组[0]索引再次出错,然后返回RightArray[0]=5,9。奇怪的是,如果我在leftarray=[4,5,6,7,8,8]和rightarray[1,2,3,5,9]上调用merge()函数,而不依赖于mergeSort(),它工作得很好,返回正确的结果,而没有奇怪的索引行为。

null

//Implement Merge Sort...
    function mergeSort(unsortedArray) {
        var leftArray = [];
        var rightArray = [];
        var result = [];
        
        //Base Case of one element
        if(unsortedArray.length <= 1){
            //alert("Array is size 1 and value: " + unsortedArray);
            return unsortedArray;
        }
        else{
            var halfwayPoint = Math.round(unsortedArray.length/2);
            
            //Sepertate unsortedArray into a left and right array
            for(var i = 0; i < halfwayPoint; i++){
                leftArray.push(unsortedArray[i]);
                //alert("leftArray: "+ leftArray + " index i = " + i);
            }
            for(var i = halfwayPoint; i < unsortedArray.length; i++){
                rightArray.push(unsortedArray[i]);
                //alert("rightArray" + rightArray + " index i = " + i);
            }
            //alert("leftArray: " + leftArray + " rightArray: " + rightArray);
            leftArray = mergeSort(leftArray);
            rightArray = mergeSort(rightArray);
            //alert("Arrays before merge = leftArray: " + leftArray + " rightArray: " + rightArray);
            result = merge(leftArray, rightArray);
            //alert("result: " + result);
        }
        return result;
    }
    
    //Helper function Merge for MergeSort
    function merge(leftArray, rightArray)
    {
        var result = [];
        while(leftArray.length > 0 && rightArray.length > 0){
            //compare first items of both lists
            //alert("top of while loop");
            //alert("leftArray[0] = " + leftArray[0] + " rightArray[0] = " + rightArray[0]);
            if(leftArray[0] >= rightArray[0]){
                result.push(rightArray[0]);
                //alert("result after push rightArray[0] " + result + " and rightArray before splice: "+ rightArray);
                rightArray.splice(0,1);
                //alert("rightArray after splce: " + rightArray);
            }
            else{
                result.push(leftArray[0]);
                //alert("result after push leftArray[0] " + result + " and leftArray before splice: "+ leftArray);
                leftArray.splice(0,1);
                //alert("leftArray after splce: " + leftArray);
            }
        }
        //alert("before leftArray add");
        if(leftArray.length > 0){
            //alert("went into left array > 0 leftArray: " + leftArray);
            result.push(leftArray);
        }
        //alert("before rightArray add");
        if(rightArray.length > 0){
            //alert("went into right array > 0 rightArray: " + rightArray);
            result.push(rightArray);
        }
        //alert("result within merge function: " + result);
        return result;
    }
    //Test Case
    var unsortedArray = [8,8,7,5,4,6,3,2,1,5,9,8,7,6,5,4,2,3,6,5,4,8];
    var sortedArray = mergeSort(unsortedArray);
    lert(sortedArray);
  
    //Problem is when Merge sort has left array and right array described below
    //the merge function will yield proper result on left array and right array
    //if called directly as it is below, however when merge is called through
    //mergeSort with leftArray and rightArray as described below it yields
    // improperResult below
    var leftArray = [4,5,6,7,8,8];
    var rightArray = [1,2,3,5,9];
    var improperResult= [1,4,2,3,5,5,9,6,7,8,8];
    var resultAct = merge(leftArray,rightArray);
    alert(resultAct);
<h1>MergeSort Problem</h1>

null

共有1个答案

邹野
2023-03-14

您需要使用array.prototype.concat()而不是.push()来连接2数组。

.concat组合两个(或更多)数组并返回一个新的数组,而push只是将目标放在数组的末尾,它不会为您连接数组。

如果记录原始结果而不是报警,您将看到

[1,2,3,4,4,数组[2],5,数组1,数组[2],数组1,数组[2],数组[4]]

很明显,您只是将数组推到了结果中。

所以在你的

if(leftArray.length > 0){
    result.push(leftArray);
}
if(rightArray.length > 0){
    result.push(rightArray);
}

你应该写信给:

if(leftArray.length > 0){
    result = result.concat(leftArray);
}
if(rightArray.length > 0){
  result = result.concat(rightArray);
}

null

    function mergeSort(unsortedArray) {
        var leftArray = [];
        var rightArray = [];
        var result = [];
        
        //Base Case of one element
        if(unsortedArray.length <= 1){
            return unsortedArray;
        }
        else{
            var halfwayPoint = Math.round(unsortedArray.length/2);
            
            //Sepertate unsortedArray into a left and right array
            for(var i = 0; i < halfwayPoint; i++){
                leftArray.push(unsortedArray[i]);
            }
            for(var i = halfwayPoint; i < unsortedArray.length; i++){
                rightArray.push(unsortedArray[i]);
            }

            leftArray = mergeSort(leftArray);
            rightArray = mergeSort(rightArray);
          
            result = merge(leftArray, rightArray);
        }
        return result;
    }
    
    //Helper function Merge for MergeSort
    function merge(leftArray, rightArray)
    {
        var result = [];
      
        while(leftArray.length > 0 && rightArray.length > 0){
            //compare first items of both lists
            if(leftArray[0] >= rightArray[0]){
                result.push(rightArray[0]);
                rightArray.splice(0,1);
            }
            else{
                result.push(leftArray[0]);
                leftArray.splice(0,1);
            }
        }
      
        if(leftArray.length > 0){
            result = result.concat(leftArray);
        }
        if(rightArray.length > 0){
          result = result.concat(rightArray);
        }

        return result;
    }
    //Test Case
    var unsortedArray = [8,8,7,5,4,6,3,2,1,5,9,8,7,6,5,4,2,3,6,5,4,8];
    var sortedArray = mergeSort(unsortedArray);
    alert(sortedArray);
  
    //Problem is when Merge sort has left array and right array described below
    //the merge function will yield proper result on left array and right array
    //if called directly as it is below, however when merge is called through
    //mergeSort with leftArray and rightArray as described below it yields
    // improperResult below
    var leftArray = [4,5,6,7,8,8];
    var rightArray = [1,2,3,5,9];
    var improperResult= [1,4,2,3,5,5,9,6,7,8,8];
    var resultAct = merge(leftArray,rightArray);
    alert(resultAct);
<h1>MergeSort Problem</h1>
 类似资料:
  • 在索引上合并是不好的做法吗?不可能吗?如果是,如何将索引转换为名为“index”的新列?

  • 问题内容: 在hive中,我希望对从最大到最小的数组进行排序,并获得索引数组。 例如,该表是这样的: 我要得到这个: 结果中的arries是初始元素的索引。我怎样才能做到这一点? 问题答案: 使用posexplode爆炸数组以获取索引和值,按值排序,收集索引数组: 经过测试,结果:

  • 我写了3个方法来实现递归合并排序,参数数量有限(没有aux、lo、mid、hi)。我认为我的工作是这样的,但它并没有返回一个排序数组,尽管它在运行时没有任何编译错误。我已经摆弄了4个小时,似乎无法弄清楚我做错了什么,没有合并一个有序数组。我只从我的助教那里得到了非常模糊的输入,并且能够修复我正在遇到的一些问题,但是该方法仍然没有对项数组进行排序。欢迎任何关于我在这里做错了什么的建议。谢谢!

  • 问题内容: 我有以下数据框: 如何合并索引以获取: 我问,因为据我了解,即使用列进行匹配。实际上,这样做我得到: 在索引上合并是不好的做法吗?不可能吗 如果是这样,如何将索引移到称为“索引”的新列中? 问题答案: 使用,默认情况下是内部联接: 或,默认情况下为左连接: 或,默认情况下为外部联接: 样品 :

  • 合并两个已有的索引比重新对所有数据做索引更有效率,而且有时候必须这样做(例如在“主索引+增量索引”分区模式中应合并主索引和增量索引,而不是简单地重新索引“主索引对应的数据)。因此indexer有这个选项。合并索引一般比重新索引快,但在大型索引上仍然不是一蹴而就。基本上,待合并的两个索引都会被读入内存一次,而合并后的内容需要写入磁盘一次。例如,合并100GB和1GB的两个索引将导致202GB的IO操

  • 首先,我对我的英语感到抱歉。我是一个使用VS Express 2013的C#初学者程序员。 我认为这是我的简单问题:我有一个组合框(cboMantello),里面有两个项目。然后我有一个按钮,使用所选项目的属性并将它们添加到我的角色统计中。另一个按钮删除该属性。 为了避免用户垃圾邮件,我禁用了第一个按钮,并设置了我的组合框。启用为false。这时问题来了。禁用组合框后,它会返回列表中的第一项,因此