这是一个合法的Quicksort实现,它的复杂性是什么?

时间:2016-09-27 00:19:57

标签: javascript algorithm quicksort

我试图编写一个快速排序,这是我的结果。它是在Javascript中,它定义了对列表进行排序。但是,我意识到我在网上看到的大多数Quicksort算法与此非常不同,感觉我的算法与我在网上看到的算法相比太容易编程,因此我很怀疑。

我完全清楚这个算法在内存方面非常低效,因为它创建了新的列表(新的内存分配),而不是进行就地排序。但是我对将这个算法教给朋友更感兴趣,这就是我试图编写最简单版本的原因。所以我的问题是,这是Quicksort算法的合法(正确实现)吗?或者它做了别的什么? (记住:我不会问这是否有效,因为我知道它不是!)

此算法的复杂性是什么?我试图计算它,我的分析是:在每次迭代中,假设两个列表(左侧和右侧)具有相同数量的元素,这将生成一个深度为logN的递归树,因为在每个级别中树,如果我们总结所有数组遍历,我们最终得到N次迭代,那么,这意味着对于每个级别,我们有N次迭代,因此复杂度为O(N Log N)。这是最好的情况,最糟糕的情况是树由于分区错误导致所有不平衡,最终导致O(N^2)复杂度。这个分析是对的吗?

function quicksort(list){


    var size = list.length;


    // Base cases
    if(size == 0) return [];    
    if(size == 1) return [list[0]];


    // Get the pivot as the middle element
    var middle = Math.floor(size/2);    
    var pivot = list[middle];

    // Init two lists. Left = less than pivot. Right = greater than pivot.
    var list_left = [];
    var list_right = [];


    // Push every element of the list into either the left or right list
    for(i=0; i<size; i++){      

        if(i == middle) continue; // Skip the pivot


        if(list[i] <= pivot)
            list_left.push(list[i]);
        else        
            list_right.push(list[i]);
    }

    // Return the concatenation of the quicksorted left list
    // pivot, and quicksorted right list (here's the recursion)

    return quicksort(list_left).concat(pivot).concat(quicksort(list_right));

}

3 个答案:

答案 0 :(得分:0)

是的,这是一个广泛接受的Quicksort功能版本。

考虑用Haskell编写的快速排序版本(取自Learn You A Haskell):

quicksort :: (Ord a) => [a] -> [a]  
quicksort [] = []  
quicksort (x:xs) =   
    let smallerSorted = quicksort [a | a <- xs, a <= x]  
        biggerSorted = quicksort [a | a <- xs, a > x]  
    in  smallerSorted ++ [x] ++ biggerSorted

首先将元素分为两组:smallerSortedbiggerSorted,然后递归地对每个分区进行排序,然后进行连接。平均情况为O(nlogn),最坏情况为O(n 2 )。

相关问题:Why is the minimalist, example Haskell quicksort not a “true” quicksort?

答案 1 :(得分:0)

我认为您的实施很简单易懂。这很好,足以教你的朋友!平均性能为O(NlogN),最差情况为O(N ^ 2)

正如您所提到的,有许多不同版本选择“枢轴”或改进版本。

以下是quicksort的另一个“就地”版本。

 function partition(a, left, right, pivotIndex)
 pivotValue := a[pivotIndex]
 swap(a[pivotIndex], a[right]) 
 storeIndex := left
 for i from left to right-1
     if a[i] <= pivotValue
         swap(a[storeIndex], a[i])
         storeIndex := storeIndex + 1
 swap(a[right], a[storeIndex]) 
 return storeIndex

 procedure quicksort(a, left, right)
 if right > left
     select a pivot value a[pivotIndex]
     pivotNewIndex := partition(a, left, right, pivotIndex)
     quicksort(a, left, pivotNewIndex-1)
     quicksort(a, pivotNewIndex+1, right)

答案 2 :(得分:-1)

平均案例绩效O(n log n) 最坏情况空间复杂度O(n)辅助(幼稚)O(log n)辅助(Sedgewick 1978)