In this section we look at how recursion can be used with structures to implement some common data structures.
We'll suppose for the purpose of this discussion that we're dealing with lists of numbers. Each node in the list will have two components: its contents, and a reference to the next node in the list. In addition we'll assume that the empty list is called nil. Thus, if we use a two-pace structure called node to represent a single node, a list containing the numbers 2, 6 and 7 would look like:
node(2, node(6, node(7, nil)))Note that the smallest possible list is nil, and every other list will contain nil as the "next field" of the last node. In list terminology, the first element is usually called the head of the list, and the rest of the list is called the tail. Thus the head of the above list is 2, and its tail is the list node(6, node(7, nil))
% add_front(List,Elem,NewList) is true if NewList is List with Elem inserted at the beginning add_front(List,Elem,NewList) :- NewList = node(Elem,List).Adding the element at the end of the list takes a little more effort, since we need to pass down through all the elements to find the last one, and add it in there. There are two cases:
Thus our code looks like:
% add_back(List,Elem,NewList) is true if NewList is List with Elem inserted at the end
add_back(nil, Elem, NewList) :-
NewList = node(Elem,nil). % New list with 1 element
add_back(node(Hd,Tl), Elem, NewList) :-
add_back(Tl, Elem, NewTl), % Add Elem to the tail of the list
NewList = node(Hd,NewTl). % Answer is Hd along with the new tail
Note that we have used some of Prolog's pattern-matching power here,
since we expect it to choose between the two predicates based on
whether the input list looks like either nil or
node(H,T). No list can match both these patterns.Save the above predicates and load them into Prolog; now try the following queries to test that they work:
Thus, if we had the following tree:
2
|
+--+--+
| |
1 6
|
+-----+-----+
| |
4 7
+-+-+
| |
3 5
we would represent it as:
node(2, node(1,nil,nil), node(6, node(4,node(3,nil,nil), node(5,nil,nil)), node(7,nil,nil))Often a binary tree will be ordered so that for any given node, the contents of its left-subtree will all be less than the current node, and the contents of the right will be greater than it. The tree shown above is ordered in this way.
Written by James Power