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

时间:2015-08-18 13:34:26

标签: javascript arrays sorting merge mergesort

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

我认为问题在于merge()函数。在阵列上调用mergeSort时:[8,8,7,5,4,6,3,2,1,5,9,8,7,6,5,4,2,3,6,5,4, 8]我得到了结果:[1,4,2,3,5,5,9,6,7,8,8]。问题的根源据我所知,在merge()函数中,当进行leftArray [0]和rightArray [0]的比较时,rightArray [0]有时会返回多个值而不是第一个索引。在我的情况下,它使用2,3和5,9。因此,当代码运行时,右边的isArray [0] = 2,3,并且在2,3被拼接出阵列之后,rightArray [0] = 5,9。以下是发生此问题时merge()内发生的情况:

步骤1

leftArray:[4,5,6,7,8,8]
rightArray:[1,2,3,5,9]
结果:[]

步骤2

leftArray [4,5,6,7,8,8]
rightArray [2,3,5,9]
结果:[1]

步骤3

(索引不正确... array [0]返回两个值)
leftArray [0] = 4
rightArray [0] = 2,3

leftArray [5,6,7,8,8]
rightArray [2,3,5,9]
结果[1,4]

步骤4

(索引不正确... array [0]返回两个值)
leftArray [0] = 5
rightArray [0] = 2,3

leftArray [5,6,7,8,8]
rightArray [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()它可以正常工作返回正确的结果而没有奇怪的索引行为。

//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>

1 个答案:

答案 0 :(得分:3)

您需要使用populate() method代替.push()来结束2 arrays.

.concat结合了两个(或更多)数组并返回一个新的array,而push只是将目标放到array的末尾,它不为你连接数组

如果您记录原始结果而非警报,则会看到

  

[1,2,3,4,4,Array [2],5,Array Array.prototype.concat(),Array [2],Array 1,Array [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);
}

    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>