F# 中的异步快排

前段时间实现了下这个算法,写的太复杂了,虽然有更简单的F# 版本,不过还是写下来留个纪念:):

    let rec quickSort (intArray : int array )= 
            match intArray with
            | empty         when empty |> Array.isEmpty -> 
                    async {return [||]}

            | singleValue   when (singleValue |> Array.length = 1) -> 
                    async {return singleValue}
              
            | multValues -> 
                    async {                            
                                //pivot
                                let p = ref 0
                                //headFlag
                                let h = ref 0
                                //tailFalg
                                let t = ref (multValues.Length - 1)
                                //tail active -- compare form tail to head ,by default 
                                let tA = ref true
                                while (!h <= !t) do
                                    if (!tA = true) then                                    
                                        if (multValues.[!t] >= multValues.[!p]) then
                                            t := !t - 1
                                        else 
                                            let temp = multValues.[!t]
                                            multValues.[!t] <- multValues.[!h]
                                            multValues.[!h] <- temp
                                            p := !t
                                            h := !h + 1
                                            tA := false
                                    else
                                        if(multValues.[!h] <= multValues.[!p]) then
                                            h := !h + 1
                                        else
                                            let temp = multValues.[!h]
                                            multValues.[!h] <- multValues.[!t]
                                            multValues.[!t] <- temp
                                            p := !h
                                            t := !t - 1
                                            tA := true

                                let leftArray = Array.sub multValues 0 (!p + 1)                            
                                let rigthArray = Array.sub multValues (!p + 1) (multValues.Length - !p - 1)

                                let! leftAsync = quickSort(leftArray) |> Async.StartChild
                                let! rightAsync = quickSort(rigthArray) |> Async.StartChild

                                let! left = leftAsync
                                let! right = rightAsync

        
                                return Array.append left right }

 代码的主要思想还是和C语言实现快排差不多,虽然有更简单的F#快排版本(大概十几行代码即可实现),不过个人认为此代码还是有点参考(或者纪念)价值的。

代码中主要就是一个递归函数quickSort,上了就使用了一个模式匹配(pattern match),判断给定数组的元素个数。这个模式匹配分成了3中情况。每种均以异步的形式进行处理。其中关键的部分是在第3种情况,也就是数组含有多个元素,其中核心代码就是:

                                let leftArray = Array.sub multValues 0 (!p + 1)                            
                                let rigthArray = Array.sub multValues (!p + 1) (multValues.Length - !p - 1)

                                let! leftAsync = quickSort(leftArray) |> Async.StartChild
                                let! rightAsync = quickSort(rigthArray) |> Async.StartChild

异步递归的实现中心轴左右两部分数组的排序。

如果你想测试这些代码,你可以这样子来试试~:

let iarr = [|1;2;3;4;2;7;5;3;2;0|]
printfn "%A" (quickSort(iarr) |> Async.RunSynchronously)

如果您觉得代码中有错误还请指出,万分感谢~:) 

原文地址:https://www.cnblogs.com/FsharpZack/p/2758823.html