Что делает его двусвязным списком, так это то, что он имеет две ссылки, а не одну, ссылку на предыдущий и следующий элемент в списке.Таким образом, мы могли бы создать структуру node(Value, Previous, Next)
и составить список вручную следующим образом: A = node(1, nil, B), B = node(2, A, nil).
.Мы могли бы сделать более длинные списки аналогичным способом, просто создав больше промежуточных переменных.
Преобразование этого обратно в «обычный» список будет выглядеть примерно так:
dl2list(node(X, _, nil), [X]).
dl2list(node(A, _, node(X,Y,Z)), [A|Rest]) :- dl2list(node(X,Y,Z), Rest).
Это не имеет особого примененияиз «предыдущего» указателя, но вы можете видеть, что он работает:
?- A = node(1, nil, B),
B = node(2, A, C),
C = node(3, B, D),
D = node(4, C, nil),
dl2list(A, L).
A = node(1, nil, _S1), % where
_S1 = node(2, node(1, nil, _S1), _S2),
_S2 = node(3, _S1, node(4, _S2, nil)),
B = node(2, node(1, nil, _S1), _S2),
C = node(3, _S1, node(4, _S2, nil)),
D = node(4, _S2, nil),
L = [1, 2, 3, 4] .
Мы также можем строить в обратном направлении, начиная с конца:
dl2listrev(node(X, nil, _), [X]).
dl2listrev(node(A, node(X,Y,Z), _), [A|Rest]) :- dl2listrev(node(X,Y,Z), Rest).
?- A = node(1, nil, B),
B = node(2, A, C),
C = node(3, B, D),
D = node(4, C, nil),
dl2listrev(D, L).
A = node(1, nil, _S1), % where
_S1 = node(2, node(1, nil, _S1), _S2),
_S2 = node(3, _S1, node(4, _S2, nil)),
B = node(2, node(1, nil, _S1), _S2),
C = node(3, _S1, node(4, _S2, nil)),
D = node(4, _S2, nil),
L = [4, 3, 2, 1]
Для создания двусвязного спискаИз списка вам нужно что-то немного более сильное, чем любой из этих:
l2dl(L, DL) :- l2dl(L, DL, nil).
l2dl([X], node(X, Prev, nil), Prev).
l2dl([X,Y|Xs], node(X, Prev, Next), Prev) :-
l2dl([Y|Xs], Next, node(X, Prev, Next)).
Это вы можете увидеть, работая в обоих направлениях здесь:
?- l2dl([1,2,3,4], X), dl2list(X, L).
X = node(1, nil, node(2, _S1, node(3, _S2, _S3))), % where
_S1 = node(1, nil, node(2, _S1, node(3, _S2, _S3))),
_S2 = node(2, _S1, node(3, _S2, _S3)),
_S3 = node(4, node(3, _S2, _S3), nil),
L = [1, 2, 3, 4]
и здесь:
?- A = node(1, nil, B),
B = node(2, A, C),
C = node(3, B, D),
D = node(4, C, nil),
l2dl(L, A).
A = node(1, nil, _S1), % where
_S1 = node(2, node(1, nil, _S1), _S2),
_S2 = node(3, _S1, node(4, _S2, nil)),
B = node(2, node(1, nil, _S1), _S2),
C = node(3, _S1, node(4, _S2, nil)),
D = node(4, _S2, nil),
L = [1, 2, 3, 4]