I have a project to do where I have to change SLList to LispList and add a few other functions. My only question is that My prof. has asked us not to create new nodes for a function called rest(), where the rest list is returned without the head.
Node* rest(){
Node* nextToHead = head -> next; //this is a pointer to the next node in the list
return nextToHead;
}
by using the pointer nextToHead, will it point to the rest of the list as well? If not, it'll be great if you guys can give me tips on how to return the list without the head and without using any other nodes.
The pointer always points to the next member of the list. If the pointer is NULL, then it is the last node in the list. A linked list is held using a local pointer variable which points to the first item of the list. If that pointer is also NULL, then the list is considered to be empty.
Generally, to visit the linked list, we can use a head pointer to keep its original linked list head like head_p = ... inputed head node... , and then use a visitor pointer to visit linked list like visitor_p = visitor_p->next . Here in your code, tmp is that head pointer .
A "node" is a concept from graph theory. A graph consists of nodes (vertices) and edges that connect the nodes. A node in C can be represented as a structure (a struct ) that has all the necessary data elements "on board" to implement a graph. Optionally a structure may be required that represents the edges.
In C++, there're two primary ways to check if a linked list is empty either by providing a pointer to the first element of a list (for example: if (root->next == NULL) { /* empty list */ } ) or by link back the list element of a linked list to its root to form a cycle ( if (root->next == root) { /*empty list */ } ).
While that technically does return a pointer to the rest of the list, or at least its nodes, the "rest" of a Lisp list is itself a Lisp list – not a different type (like node
).
A "Lisp list" doesn't have a head as such; it looks pretty much like this:
struct List
{
ElementType data;
List* next;
};
and has the operations
ElementType first(List* l) { return l->data; } /* or "car" */
List* rest(List* l) { return l->next; } /* or "cdr" */
or, as members:
ElementType List::first() { return data; }
List* List::rest() { return next; }
Note that every node in a Lisp list is the "head" of a sublist of the entire list.
When you return a Node
pointer, everything the Node
exposes can be used and abused. This includes the rest of the list.
The usual solution is to abstract the Node
behind an iterator so that the user doesn't even see a Node
. All they get is an iterator. The iterator still provides access to the rest of the list, so you have to restrict things even further
SingleNode rest(){
return SingleNode (head -> next);
}
where SingleNode
looks something like
class SingleNode
{
Node* node;
public:
MyDataType& operator*()
{
return node->data;
}
};
If you can't do this,
Node
private
to limit access.SLList
a friend of Node
so only Node
and SLList
can see the links. Example:
struct Node
{
friend class SLList;
MyDataType data;
// other public stuff
private:
Node * next;
// other private stuff
};
Now the holder of a Node
pointer can not see the rest of the list. They can still blow up the list by damaging the Node
they have access to, but they have to work at it.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With