我的Quicksort实现因数字递减而失败

时间:2016-08-02 12:41:14

标签: javascript algorithm sorting quicksort

我正在为快速排序代码编写代码。

代码如下,

function quickSort(inputArray){
  var pivotIndex = undefined;
  var low_Index = undefined;
  var high_Index = undefined;

  pivotIndex = inputArray.length - 1;
  low_Index = 0;
  high_Index = (inputArray.length > 2) ? (inputArray.length - 2) : 0;

  partition(pivotIndex,low_Index,high_Index);

  function partition(pivot_Index,low_Index,high_Index){
    var hasSwapped = false
    var temp = 0;

    for(var low = low_Index; low < pivot_Index; low++){

        if(inputArray[low] > inputArray[pivot_Index]){
            hasSwapped = true;
            temp = inputArray[low];
            inputArray[low] = inputArray[high_Index];
            inputArray[high_Index] = inputArray[pivot_Index];
            inputArray[pivot_Index] = temp;
            pivot_Index = high_Index;
            high_Index--;
            low--;              
        }
    }


    //console.log("PIVOT_INDEX "+inputArray[pivot_Index]);

    if(pivot_Index < inputArray.length - 1){

        if((pivot_Index + 1) < inputArray.length - 1){
            partition(inputArray.length - 1,(pivot_Index + 1),inputArray.length - 2);   
        }

        if((pivot_Index - 2) >= 1){
            partition((pivot_Index - 1),0,(pivot_Index - 2));   
        }


      }


  }



  return inputArray;

}

以上代码运行以下输入

console.log(quickSort([3,7,8,5,2,1,9,5,4]));
console.log(quickSort([4,7,3,15,2,1]));
console.log(quickSort([4,7,3]));
console.log(quickSort([7,3]));

输出

rahul@rahul:~/myPractise/Algo$ node sorting.js 
[ 1, 2, 3, 4, 5, 5, 7, 8, 9 ]
[ 1, 2, 3, 4, 7, 15 ]
[ 3, 4, 7 ]
[ 3, 7 ]

但是无法跟随所有数字按降序排列的输入

console.log(quickSort([15,12,10,7,4,1]));

rahul@rahul:~/myPractise/Algo$ node sorting.js 
[ 1, 12, 10, 7, 4, 15 ]
rahul@rahul:~/myPractise/Algo$ 

我认为原因是我的枢轴索引指向15是最大数字,因此没有被替换。

如何更改代码,以便上述输入算法有效?

注意:我从维基百科中显示的图表中得到了快速排序的解释

大家好,

我通过添加代码

解决了上述问题
    if(inputArray[low_Index] > inputArray[high_Index]){
        temp = inputArray[low_Index];
        inputArray[low_Index] = inputArray[high_Index];
        inputArray[high_Index] = temp;      
        pivot_Index = high_Index;           
    }
如果在函数内部条件&#34;分区&#34;

,则在for循环及其上方

所以现在我的代码看起来像这样

function quickSort(inputArray){
    var pivotIndex = undefined;
    var low_Index = undefined;
    var high_Index = undefined;

    pivotIndex = inputArray.length - 1;
    low_Index = 0;
    high_Index = (inputArray.length > 2) ? (inputArray.length - 2) : 0;

    partition(pivotIndex,low_Index,high_Index);

    function partition(pivot_Index,low_Index,high_Index){       
       var temp = 0;

       console.log("\nPivot Number : "+inputArray[pivot_Index]);
       console.log("input Array : "+inputArray);
       console.log("partitioned array : "+inputArray.slice(low_Index,pivot_Index+1));

       for(var low = low_Index; low < pivot_Index; low++){

        if(inputArray[low] > inputArray[pivot_Index]){

            temp = inputArray[low];
            inputArray[low] = inputArray[high_Index];
            inputArray[high_Index] = inputArray[pivot_Index];
            inputArray[pivot_Index] = temp;
            pivot_Index = high_Index;
            high_Index--;
            low--;              
        }
      }

      // added if condition, which solves my problem
      if(inputArray[low_Index] > inputArray[high_Index]){
        temp = inputArray[low_Index];
        inputArray[low_Index] = inputArray[high_Index];
        inputArray[high_Index] = temp;      
        pivot_Index = high_Index;           
      }




      if(pivot_Index < inputArray.length - 1){

        if((pivot_Index + 1) < inputArray.length - 1){
            partition(inputArray.length - 1,(pivot_Index + 1),inputArray.length - 2);   
        }

        if((pivot_Index - 2) >= 1){
            partition((pivot_Index - 1),0,(pivot_Index - 2));   
        }


      }


    }//partition



    return inputArray;

}

运行上面的输入代码后

console.log(quickSort([15,12,10,7,4,1]));

输出如下,

rahul@rahul:~/myPractise/Algo$ node sorting.js 

Pivot Number : 1

input Array : 15,12,10,7,4,1
partitioned array : 15,12,10,7,4,1

Pivot Number : 15
input Array : 1,12,10,7,4,15
partitioned array : 12,10,7,4,15

Pivot Number : 7
input Array : 1,4,10,7,12,15
partitioned array : 1,4,10,7

Pivot Number : 15
input Array : 1,4,7,10,12,15
partitioned array : 10,12,15
[ 1, 4, 7, 10, 12, 15 ]
rahul@rahul:~/myPractise/Algo$ 

代码正常运行。

1 个答案:

答案 0 :(得分:0)

当数组是数组的最大数字时,partition函数无法正常工作([2,1,3]不会排序...)。 确实,这种情况永远不会成真:

if(inputArray[low] > inputArray[pivot_Index]){

因此pivot_Index永远不会改变,所以最后一个条件总是假的:

if(pivot_Index < inputArray.length - 1){

除了你用错误的参数递归调用partition函数:

partition(inputArray.length - 1,(pivot_Index + 1),inputArray.length - 2);

实际上,您总是采用整个数组(inputArray.length - 2)的最后一个元素而不是子数组。所以你最终会得到类似的东西:

                  [A,B,C,D,E,F]
        [A,B,C,D]              [E,F]
    [A,B]    **[C,D,E,F]** WRONG

您应该简化代码。从这样的事情开始:

function quicksort(array, lo, hi){
    if (lo < hi){ 
        indicePivot  := partition(array, lo, hi) // partition your array [values < pivot ... , pivot, values > pivot ...]
        // Divide and conquer: recursively call quicksort on sub arrays [values < pivot] and [values > pivot]
        quicksort(array, lo, indicePivot – 1) 
        quicksort(array, indicePivot + 1, hi)
    }
}

你的分区功能:

function partition(array, lo, hi){
   indicePivot = hi;
   // do the magic to have [values < pivot ..., pivot, values > pivot]
   // ...
   return indicePivot;
}