【发布时间】:2012-01-15 19:12:31
【问题描述】:
Prolog 有一种独特的处理方式,尤其是因为实际上每个操作都涉及一种或另一种递归。
每种语言都有的一个经典示例是将整数列表按升序排序。
对随机整数列表进行排序的最佳方式是什么(不使用太多内置谓词,当然这会排除 sort/2 谓词)?
【问题讨论】:
Prolog 有一种独特的处理方式,尤其是因为实际上每个操作都涉及一种或另一种递归。
每种语言都有的一个经典示例是将整数列表按升序排序。
对随机整数列表进行排序的最佳方式是什么(不使用太多内置谓词,当然这会排除 sort/2 谓词)?
【问题讨论】:
Roman Barták 的 Prolog Programming 网站提供 examples of different sort algorithms,以优化的快速排序结束。
quick_sort2(List,Sorted):-q_sort(List,[],Sorted).
q_sort([],Acc,Acc).
q_sort([H|T],Acc,Sorted):-
pivoting(H,T,L1,L2),
q_sort(L1,Acc,Sorted1),q_sort(L2,[H|Sorted1],Sorted)
【讨论】:
据我所知,最好的排序算法直接用 Prolog 编写,不参考任何特殊的内置函数,使用某种形式的归并排序。
一个常见的优化是开始合并的不是长度为 1 的列表,而是已经排序的段。
也就是说,要对列表 [4,5,3,6,2,7,1,2] 进行排序,列表 [4,5],[3,6],[2,7],[1,2] 将被合并。
这可以通过组合排序列表来进一步优化,不仅在升序方向,而且在另一个方向。对于上面的示例,这意味着已排序的段按如下方式组装:
[4,5|_]
[3,4,5|_]
[3,4,5,6|_]
...
请注意,在 Prolog 中,可以直接在开头和结尾扩展列表。
因此,我们只需要合并[1,2,3,4,5,6,7] 和[2]。
使用 Richard O'Keefe 的原始实现 (~1984) 的当前系统是 Ciao-Prolog in
ciao-1.15/lib/sort.pl。
【讨论】: