I have been learning C++ for a while, and just started looking at linked lists recently. I can construct a template class List with the usual functions insert/remove from back/front. Now I came up with an exercise that asks me to write a function to handle insertions/deletions anywhere in the list.
Please bear in mind that my questions are very basic.
The problem I have is that I see the question as ambiguous. What kind of information does the function require? For instance, for deletion, I can come up with several candidates:
1) delete the first node that has a particular value (argument: value)
2) delete all nodes with a particular value (argument: value)
3) delete a particular node (argument: pointer to that node)
1) and 2) I can easily code. 3) is harder but I can also do it. I just don't see the point in 3). Is it usual to manipulate nodes (outside the list definition) when using lists? As in, is it usual for a program using lists to actually manipulate pointers to the nodes?
What is the usual meaning of "delete anywhere" in this setting?
Similarly, for "insert anywhere", the wording is strange. What does "anywhere" mean? Is the place in the linked list supposed to be given by a particular node?
In linked list you have constant time access to first element. So delete/insert anywhere means the place that exists between first and last element. Basically you need to have 2 iterators. When you find the place you want remove/insert a element, you should refer to the object just before it. because you have not access to the prev element, only to the next one:
Let's say our linked list looks like this:
E0->E1->E2->E3->E4
If you want remove E3, you need to have iterator set on E2 so that you could correct pointers for E2->next.
Good reference is the book Standard Library wrote by Nicolai M. Josuttis. The problem you have encountered is widely described there.
node*insert(node*head,int d){
node*temp=new node;
temp->data=d;
if(head==NULL){
temp->next=NULL;
head=temp;}
else
{node*curr=head,*pre=NULL;
while (curr!=NULL && curr->data<temp->data)
{
pre=curr;
curr=curr->next;
}
temp->next=curr;
if(pre==NULL)
head=temp;
pre->next=temp;
}
return head;
}
Related
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.
In the recent assignment, we are asked to implement a hashmap in C++ without the techniques provided in STL.
I'm stack on one of the functions -- copy constructor. After searching the google, I found a valid solution in the question:
Writing a valid copy constructor for a hash map in C++
But I can't totally understand it. Could anyone please help explain
1. why we need to use a pointer-to-pointer Node** p = &hashTable[i]; ?
2. what is the logic in the while loop?
3. especially, what does this code p=&c->next; mean?
Firstly, there are many different types of hash table implementations, so any specific one you find online may or may not yield insights into what you'll need to do for your own implementation. That said...
p is initially pointed at the head element for the bucket, which is the Node*s at [this->]hashTable[i]. It's initially used to set it to NULL. As you're dealing with Node*s, a Node** is a natural way to keep track of their locations.
each iteration of the while loop duplicates the next Node that's in bucket [i] in hm; the duplicate is created in new memory at c, and *p (which tracks the linked list positions being created for the *this object under construction) is updated to point thereto.
p=&c->next; means p is set to the next member of the newly created Node (at address c): that next pointer must be initialised by the Node(const Node&) constructor to nullptr/NULL/0, or the linked lists created wouldn't terminate properly. Only if there are more elements in the linked list of colliding elements to be copied, the next iteration will overwrite *p and therefore the next member of the previously added Node with the next value of c.
Summarily, you're looking at a loop that copies amountOfBuckets linked lists. If you're not familiar with linked list operations, you'd be better off writing a linked list class first and getting that working, then use it to help implement the hash table.
I asked a question last night on how to sort() a double linked list in C++.
I managed to get it to work, but now I'd like to merge two lists, but I can't
get it to work. I don't have much code, I'm sorry. Everything I tried
absolutely made no sense. I'd just like if someone could give me some hints on
where to start, or on how to do this, with the information I'm going to
provide.
This is what I had in the beginning:
void next() { if (curr != tail) curr = curr->next; }
I believe I only need these.
I looked at some exemples online, but it doesn't make any sense to me. It
seems so different than what I have right now. Apparently it should be A LOT
easier than doing a sort function, which I had barely any trouble doing.
Any explanation/hints would be greatly appreciated! And I'm sorry once again
for the lack of code, I just don't know where to start.
You can actually do this in multiple ways
Take the two sorted lists, and literally merge them so that you end up with a sorted list
Take the two sorted lists, and create a third new list that contains elements from both the lists in sorted order
Merge the two sorted/unsorted lists, and then sort the resulting list
It looks like you're trying to do no. 3 here.
In which case, you can just
Start from head of the current list, and go to next until you reach the last element
Set curr->next = other_list.head
Call sort on the current list
This would however destruct the original list. I think it's better to copy them to a third list.
for_each(auto x in list2name)
{
list1name.push_back(x);
}
or if you're using C++ 11
for(auto x : list2name)
{
list1name.push_back(x);
}
If you have used the std::list as a linked list you can always use the existing merge() function http://www.cplusplus.com/reference/stl/list/
If this is something you have implemented yourself just get the tail of one of the lists and use something like this:
tail = list_1.get_tail();
tail.set_next(list_2.get_head())
Basically getting the last entry in list 1 and then setting the next elemt to be the first element of list 2.
I'm still a bit confused what you're after, but this is the most basic way I can think of.
Then again, I might be completely off.
Good luck
a) I have seen a lot of examples of this question in stackoverflow but I am still having problems understanding how does it know which node it is referring when call functions like insertAfter(Node n, Object o). If we say insert after node 2, how does linkedlist know which node is node 2?
b) in the previous posts in stackoverflow, it is said there is a pointer to a node that you want to insert after or before, that is why we get constant time operations. does that mean, just like we have to head and tail in linked list, we also have a pointer to each node?
would really appreciate help in understanding this.
If deletion is done using key then your point is valid because we dont know the position of the element to be deleted and thus finding key in the list makes its time linear in the length of the queue. But at places where it is written to be Constant time is deletion by address. So one may always move to that address and delete the node in constant time.
Note : This ain't possible with singly linked list.
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.