Sal*_*lil 6 sorting haskell quicksort difference-lists
我正在学习haskell,我看到的函数定义是:
quickSort (x : xs) = (quickSort less) ++ (x : equal) ++ (quickSort more)
                 where less = filter (< x) xs
                       equal = filter (== x) xs
                       more = filter (> x) xs
Run Code Online (Sandbox Code Playgroud)
是否可以只用一次遍历列表而不是3来编写它?
ham*_*mar 13
你的意思是这样的?
quicksort [] = []
quicksort (x:xs) = quicksort less ++ (x : equal) ++ quicksort more
  where (less, equal, more) = partition3 x xs
partition3 _ [] = ([], [], [])
partition3 x (y:ys) =
  case compare y x of
    LT -> (y:less, equal, more)
    EQ -> (less, y:equal, more)
    GT -> (less, equal, y:more)
  where (less, equal, more) = partition3 x ys
Run Code Online (Sandbox Code Playgroud)
请注意,这并不是真正的快速排序,因为真正的快速排序就位.
小智 9
它似乎没有改善任何东西,但:
qs (x:xs) = let (a,b) = partition (< x) xs in (qs a) ++ [x] ++ (qs b)
Run Code Online (Sandbox Code Playgroud)
        虽然很晚,这里的版本应该不会泄漏太多空间(并且似乎运行速度比其他3路版本快两倍):
qsort3 xs = go xs [] 
  where
    go     (x:xs) zs       = part x xs zs [] [] []
    go     []     zs       = zs
    part x []     zs a b c = go a ((x : b) ++ go c zs)
    part x (y:ys) zs a b c =
        case compare y x of
                  LT -> part x ys zs (y:a) b c
                  EQ -> part x ys zs a (y:b) c
                  GT -> part x ys zs a b (y:c)
Run Code Online (Sandbox Code Playgroud)
这解决了使用元组的可能问题,其中let (a,b) = ...实际上被转换为let t= ...; a=fst t; b=snd t导致即使在a已经被消费和处理之后的情况下,它仍然保持活着,作为元组的一部分t,b以便从中读取 - 尽管当然完全没必要.这被称为"Wadler pair space leak"问题.或许GHC(和-O2)比这更聪明.:)
此外,这显然使用差异列表方法(谢谢,hammar),这也使它更有效(大约比使用元组的版本快两倍).我认为part使用累加器参数,因为它以相反的顺序构建它们.
|   归档时间:  |  
           
  |  
        
|   查看次数:  |  
           704 次  |  
        
|   最近记录:  |