标准ML中的True QuickSort

时间:2017-02-07 22:15:19

标签: quicksort sml

根据问题(和讨论)" RosettaCode's Standard ML solution" Why is the minimalist, example Haskell quicksort not a "true" quicksort?是Quicksort的一个非常慢的版本,如果它在标准ML中如何看起来像功能性Quicksort表现符合Hoare's algoritm的复杂性?

viewFor annotation

也就是说,在有意义的情况下使用函数式编程的某些方面。与需要封装其就地分区的Haskell版本不同,除了语法之外,是否需要SML中的Quicksort以任何方式与C版本有所不同?函数是接受数组/向量还是花费 O(n)转换列表的时间不太相关。

编辑:关于John Coleman的评论的重新提问。

2 个答案:

答案 0 :(得分:2)

这是我的尝试:

fun swap(A,i,j) = 
    let
        val t = Array.sub(A,i)
    in
        Array.update(A,i,Array.sub(A,j));
        Array.update(A,j,t)
    end

fun firstAfter(A,i,f) =
    if f(Array.sub(A,i)) then i else firstAfter(A,i+1,f)

fun lastBefore(A,j,f) =
    if f(Array.sub(A,j)) then j else lastBefore(A,j-1,f)

fun partition(A,lo,hi)=
    let 
        fun partition'(A,lo,hi,pivot) = 
            let 
                val i = firstAfter(A,lo,fn k => k >= pivot)
                val j = lastBefore(A,hi,fn k => k <= pivot)
            in
                if i >= j then 
                    j
                else
                (
                    swap(A,i,j);
                    partition'(A,i+1,j-1,pivot)
                 )
             end
   in
      partition'(A,lo,hi,Array.sub(A,lo))
   end

fun quicksort(A,lo,hi) = 
    if hi <= lo then
        ()
    else
        let
            val p = partition(A,lo,hi)
        in
            (
                quicksort(A,lo,p);
                quicksort(A,p+1,hi)
             )
        end;

fun qsort A = quicksort(A,0,Array.length A - 1); 

跟随维基百科中描述的Hoare's algorithm非常接近,但是使用递归而不是循环,并且有一些功能性的方法来寻找交换的索引对。毫无疑问,这与2或3行伪快速排序一样优雅,这通常在函数式编程的介绍性处理中教导,并且它并没有真正展示函数式编程的功能。希望有人比我更了解SML,可以想出一个更惯用的SML qsort。

答案 1 :(得分:0)

您可以在我的 github 存储库中找到一些用 Standard ML 编写的排序算法https://github.com/Khanzadeh-AH/sorting_algorithms_SML

fun pivot_split([], pivot) = ([],[])
|   pivot_split(h::t, pivot) =

        let
            val (L,R) = pivot_split(t, pivot)
        in

            if h < pivot then (h::L, R)
            else (L, h::R)
        end;
    
    

fun quicksort([]) = []
|   quicksort([a]) = [a]
|   quicksort(h::t) =
        let
            val (L, R) = pivot_split(t, h)
        in
            quicksort(L)@[h]@quicksort(R)
        end;



pivot_split([12,3,5,67,1,2,3,5,7],3);

quicksort([12,3,5,67,1,2,3,5,7]);