[英]How does quicksort in Haskell work?
On the Haskell website , there's this example quicksort implementation : 在Haskell网站上 ,这个示例是quicksort实现 :
quicksort :: Ord a => [a] -> [a]
quicksort [] = []
quicksort (p:xs) = (quicksort lesser) ++ [p] ++ (quicksort greater)
where
lesser = filter (< p) xs
greater = filter (>= p) xs
There is an explanation on the site, but I have a couple of questions that I didn't see were addressed ... 该网站有一个解释,但我有几个问题,我没有看到解决...
lesser
and greater
are created, with <
, >=
— Ord
is a typeclass restricting a
to be orderable — if it wasn't used, you wouldn't be able to use <
or >=
. lesser
和greater
的创建,以<
, >=
- Ord
是一个类型类限制a
要订购-如果没有使用它,你就不能使用<
或>=
。 xs
— pattern match splits input list into p
and xs
. xs
一部分 - 模式匹配将输入列表拆分为p
和xs
。 Here's crappy ASCII visualisation: 这是糟糕的ASCII可视化:
qs [5, 5, 6, 3, 1]
|
qs [3, 1] ++ [5] ++ qs [5, 6]
| | |
qs [1] ++ [3] ++ qs [] | qs [] ++ [5] ++ qs [6]
| | |
[1, 3] ++ [5] ++ [5, 6]
\ | /
\-------------------/
|
[1, 3, 5, 5, 6]
where is the actual comparison/swap done on two elements for a re-order?
对于重新订购,两个元素的实际比较/交换在哪里? Is this handled by the
Ord
(ordered) type definition itself.这是由
Ord
(有序)类型定义本身处理的。 So the type enforces this condition of being ordered?那么类型强制执行这个被命令的条件?
Ord
mean? Ord
是什么意思? Ord
just means that a
should be comparable with itself or in stricter terms operations such as >
, <
, and ==
should be defined for a
. Ord
只是意味着a
应该与自身相比或者更严格的术语,例如>
, <
和==
应该为a
定义。 You can think of it as a constraint on the method. 您可以将其视为该方法的约束。
And the answer is the last pattern: 答案是最后一种模式:
quicksort (p:xs) = (quicksort lesser) ++ [p] ++ (quicksort greater)
where
lesser = filter (< p) xs
greater = filter (>= p) xs
At run time, the program is going to get an array and the array must meet either of these two patterns: 在运行时,程序将获得一个数组,并且数组必须满足以下两种模式之一:
Pattern 1#: It is empty, in which case the function returns that same empty array and stops. 模式1#:它是空的,在这种情况下,该函数返回相同的空数组并停止。
Pattern 2#: It is not empty or in other words, there is a head element p
appended to a tailing array xs
. 模式2#:它不是空的,换句话说,有一个头元素
p
附加到尾部数组xs
。 In such a case, the function is told to put p
in the middle, put all elements of xs
that are less than p
on the left (as defined by lesser
) of p
and all elements of xs
that are greater than or equal to p
on the right of p
. 在这样的情况下,函数被告知把
p
在中间,放的所有元素xs
是小于p
的左(通过定义lesser
)的p
和的所有元素xs
是大于或等于p
在右边的p
。 Furthermore, the function is finally told to apply itself (ie, the same function quicksort
) on lesser
(which as we defined above, is the array on the left hand side of p
) and greater
(which as we defined above, is the array on the right hand side of p
). 此外,最后告诉函数将自身(即,相同的函数
quicksort
)应用于lesser
(如上所述,是p
的左侧的数组)和greater
(正如我们在上面定义的那样,是数组)在p
)的右侧。 As you can see, this will go on till you are left with a zero sized array and pattern 1# terminates the function. 正如您所看到的,这将持续到您留下零大小的数组并且模式1#终止该函数。
Finally, whenever those recursive calls terminate the function shall return the array: 最后,每当这些递归调用终止时,函数都将返回数组:
sortedlesser ++ p ++ sortedgreater
where sortedlesser
is the array that resulted from the application of quicksort
on lesser
and sortedgreater
is the array that resulted from the application of quicksort
on greater
. 其中
sortedlesser
是起因于应用的阵列quicksort
上lesser
并且sortedgreater
是起因于应用的阵列quicksort
上greater
。
the 'greater' predicate defines items '>= p' (the pivot), so doesn't this mean we'll end up with an extra pivot [p] in resulting list of the function, due to the '++ [p]' item?
'更大'的谓词定义了项'> = p'(枢轴),所以这并不意味着我们最终会在函数的结果列表中得到一个额外的pivot [p],因为'++ [p ]'项目?
No, this is not how pattern matching works. 不,这不是模式匹配的工作原理。 It is saying all elements in
xs
that are greater than or equal to p
. 它说
xs
中的所有元素都大于或等于p
。 By definition p
itself is out of xs
. 根据定义,
p
本身不在xs
。 If there are duplicates of p
in xs
then they will fall on the right hand side. 如果在
xs
有重复的p
,那么它们将落在右侧。 Note that this choice will preserve the natural ordering of the original array. 请注意,此选择将保留原始数组的自然顺序。
Note that you can write this even shorter and more performant (as partition
scans the original list only once) using 请注意,您可以使用更短更高效的内容(因为
partition
仅扫描原始列表一次)
quicksort [] = []
quicksort (p:xs) = (quicksort lesser) ++ [p] ++ (quicksort greater)
where (lesser, greater) = partition (< p) xs
If you want only one line: 如果您只想要一行:
qsortOneLine s = case s of{[]->[];(x:xs)->qsortOneLine [y | y<-xs, y<x] ++ x : qsortOneLine [y | y<-xs, y>=x]}
If you want more performant code: 如果您想要更高性能的代码:
qsort3 :: Ord a => [a] -> [a]
qsort3 x = qsort3' x []
qsort3' [] y = y
qsort3' [x] y = x:y
qsort3' (x:xs) y = part xs [] [x] []
where
part [] l e g = qsort3' l (e ++ (qsort3' g y))
part (z:zs) l e g
| z > x = part zs l e (z:g)
| z < x = part zs (z:l) e g
| otherwise = part zs l (z:e) g
http://en.literateprograms.org/Quicksort_(Haskell ) http://en.literateprograms.org/Quicksort_(Haskell )
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.