If the last node of a linked list is connected to the first node, it makes a ring.
Then how would you identify which of the nodes in the linked list is the first node and the last one?
You wouldn't. If it is a ring, then first and last are meaningless. Any node can be first or last.
If you define "first" as "created first", then you would probably want to add some sequencing information to the nodes to be able to know that.
Presumably there would be a pointer to the first node of a linked list (you need a way of entering the list). Additionally it is convenient in this case to maintain a pointer to the last node in the list.
If you are more specific about what you need to know I can be more helpful.
What you are describing is a circularly linked list. It is possible to know both the first and last item in the list based off just maintaining the last node. Logically that requires it's successor to be the first node.
wikipedia has a bit more about it: https://en.wikipedia.org/wiki/Linked_list#Circularly_linked_list
If you are trying to implement a circular list, have a look here http://en.wikipedia.org/wiki/Linked_list#Circularly_linked_list
When you create the Linkedlist, store the address of the first node in a variable(preferably a private variable) so that at any point of time , you can compare this address with the current node's address
Related
There will be multiple (closely) related questions instead of a single one. For our comfort, I will number them accordingly.
Based on this Wikipedia article, this question and lectures, I think I already understand the idea behind sentinel nodes and their usage in linked lists. However, a few things are still not clear to me even after reading these materials.
I was given a basic implementation of a doubly linked list (it stores only int values) and the task is to change the implementation so it uses a sentinel node like this:
Illustrative image (not allowed to embed images yet, sorry)
Question 1
I am assuming that the head variable of the list will point to the first real node (the one after sentinel node) and the tail variable will simply point to the last node. Am I correct or should the head point to the sentinel node? I am asking for a best-practice or the most standard approach here.
Question 2
I understand that when searching for a value in the list, I no longer have to check for nullptr since I am using a sentinel node. Since the list basically formed a circle thanks to the sentinel node, I have to terminate it after iterating through the whole list and reaching it. Can I do it by putting the value I am looking for in the sentinel node and use it as a sentinel value of sorts and then check if the result is returned from the sentinel node when the loop ends? Some sources claim that sentinel nodes should not store any values at all. Is my approach correct/reasonably effective?
Question 3
When simply iterating and not searching for a particular value (e.g. counting nodes, outputting the whole list into the console), do I have to check for the sentinel node the same way as I would for a nullptr (to terminate the iterating loop) or is there a different or smarter way of doing this?
Answer 1
Yes this is a valid position for the sentinelnode to take. head and tail can point to the actual beginning and end of the data. But your add and delete functions will need to be aware of the aberrations caused at the list boundaries by virtue of the sentinel node
Answer 2
Yes this is a valid search strategy and is infact called the Elephant in Cairo technique
Answer 3
Yes, the purpose of the sentinel node is to let you know that it is the sentinel node. You could just maintain a constant pointer (or whatever your lang of choice supports) to this sentinel node to check if you are at the sentinel node or just stick a flag in the node.
My question comes up when I'm doing some linked list practice. My task here is to combine two linked lists into one, so I will first need to get the address of the last node of the first linked list and assign the first node of the second list to the next of the last node in my first linked list, namely
list1->last->next = list2->first;
So we all know that, list1.last->next is NULL, and let's say what if I do:
Node * lastNext = list1->last->next;
lastNext = list2->first;
Will this work?
Thanks guys!
No, it will not work, and the reason why has nothing to do with NULL. It has to do with the fact that all you're doing here is changing the value of a local pointer variable. You aren't affecting the list in any way. Specifically, you aren't changing the value of list->last->next.
If lastNext was a reference:
Node *&lastNext = list1->last->next;
it would be a different matter. But it isn't. And NULL would still not come into play.
I have do to an assignment where we are to do a doubly linked list with no head or tail. I want to find examples of this very thing so I can understand it better. Now a Circular Doubly Linked List C++ is just that is it not? When I look up this in google I get examples with head and/or tail. I just want clarification so I do not make a mistake and be way behind. I have asked the professor but I do not think he checks his emails as often as I would like.
Simple:
A "linked list" is when each node contains a pointer to the next.
A "doubly linked list" is where each node contains both a forward pointer (to the next element), and a backward pointer (to the previous element).
Finally, a "circular doubly linked list" has a finite length - the final element points forward to the first, in a "circle".
Every link list be composed of nodes.
Every node will be composed of tuples which are composed of (elements, links).
Every element is the very thing that is contained.
Every link is a pointer to another node.
Next circular linked list are those that have the link connected in such a way where when one transverse the links one can arrive to the start without any change in direction.
This is can be done singularly or through multiple directions.
An interview question:
copy linked list with random link in each node, each node has a variable,which randomly
points to another node in the list.
My ideas:
Iterate the list, copy each node and its pointed nodes by its variable and add a sentinel at the end and then do the same thing for each node.
In the new list, for each node i, separate each list ended with sentinel and use i's variable points to it.
It is not efficient in space. It is O(n^2) in time and space.
Better ideas?
I think you can pinch ideas from e.g. Java
Serialisation, which recognises when pointers point to nodes already serialised, so that it can serialise (and then deserialise) arbitrary structures reasonably efficiently. The spec, which you can download via a link at http://docs.oracle.com/javase/1.4.2/docs/guide/serialization/index.html, says that this is done but doesn't say exactly how - I suspect hash tables.
I think copying is a lot like this - you don't even need to know that some of the pointers make up a linked list. You could use a depth first search to traverse the graph formed by the nodes and their pointers, putting the location of each node in a hash table as you go, with the value the copied node. If the node is already present you don't need to do anything except make the pointer in the copied node point to the copy of the node pointed to as given by the hash table. If the node is not already present, create the copy, put the node in the hash table with the address of the copy as its value, and recursively copy the information in the node, and its pointers, into the newly made copy.
This is a typical interview question. You can find many answers by using Google. This is a link I think is good for understanding. But please read the comments too, there are some errors in the main body: Copy a linked list with next and arbit pointer
Hello I dont know if there is a command in C++ which I can use to jump directly to 5th node in a linked list? I know with : p->next i can try to go to the next node but what if I want to go to the 56th right awat is there a way ? like p->next(56) or something ? Thanks
If the linked list does not have a command like p->get(56) built in then you have to write your own function that uses a for loop. It takes the list and the number of the element you want and then calls next that number of times.
There is no such "command". A characteristic of a linked list is that it is slower to locate a particular node by position. Unless of course, you've already stored a pointer to that node.
If this is a problem, then a linked list is not the correct data structure for your purposes.
At least if you have an iterator of the category InputIterator (those of std::list are of this category) you can use std::advance. For example, if you want to get the iterator pointing to the fifth element from the beginning of the list:
std::list<int> l;
// ...
std::list<int>::iterator it = l.begin();
std::advance(it, 4);
// Now it points to the fifth element
But as the others already mentioned: A linked list isn't supposed to have random access. You always have to travel through it in order to get a certain entry. And thus std::advance will perform very poor for large lists.
C++ doesn't provide a linked list type that you can access at that level. It does have std::list<>, which provides encapsulation. You can not directly index into a linked list... though you can advance 56 steps from the first (or some other already-found) element, but each node must be traversed and this is relatively inefficient. If you need better performance, you should reconsider your choice of container: perhaps a vector or map would be more appropriate.
This is the nature of linked lists. You'll have to traverse all the way to the nth element.