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)
如果您觉得代码中有错误还请指出,万分感谢~:)