Prolog差异列表 - mergesort

时间:2013-03-27 00:40:30

标签: prolog difference-lists

我必须编写谓词,将一个列表分成两个列表(对分):

halve(X-Y, X-Z, Z-Y) :- halve_pom(X-Y, X-Y, Z), !.

halve_pom(Z-Y, Y-Y, Z).

halve_pom([_|A]-Y, [_,_|B]-Y, Z) :- halve_pom(A-Y, B-Y, Z).

这很简单,但现在我必须编写将进行mergesort的算法 - 我不知道。此算法必须使用差异列表。

请帮忙。

1 个答案:

答案 0 :(得分:1)

不,它不是“容易”,因为它不起作用,不幸的是。 halve([1,2,3]-[],A,B)不起作用; halve_pom([1,2,3]-[],A,B)也不起作用。此外,目前还不清楚您更喜欢哪种拆分方案,[1,2,3,4,5,6,7] -> ([1,3,5,7] , [2,4,6])-> ([1,2,3,4] , [5,6,7])

如果您的halve谓词有效,那么您要做的就是定义merge,它将合并列表的两半,按顺序。然后,

mergesort(A,S):- halve(A,B-[],C-[]), mergesort(B,SB), mergesort(C,SC),
  merge(SB,SC,S-[]).

请注意,您可能会使用普通列表A来调用它,即halve谓词应该将其第一个参数视为普通列表(即不是差异列表)。

另见What does the "-" symbol mean in Prolog when dealing with lists?'-'是不必要的;相反,它的两个组成部分应该用作谓词的两个独立参数。


因此,编码halve的一种方法是

halve([A,B|C],[A|X]-ZX,[B|Y]-ZY):- halve(C,X-ZX,Y-ZY). 
halve([A],[A|X]-X,Y-Y). 
halve([],X-X,Y-Y).

可以使用相同的方法来编码merge

merge(SB,SC,S-Z):- SB=[A|B], SC=[C|D], A=<C, S=[A|T], merge(B,SC,T-Z).
merge(SB,SC,S-Z):- SB=[A|B], SC=[C|D], A>C,  ... ,    ... .
merge(SB,SC,S-Z):- SB=[A|B], SC=[],          ... ,    ... .
merge(SB,SC,S-Z):- SB=[], SC=[C|D],          S=[C|T], ... .
merge([],[],Z-Z).