| devonrevenge (897) | |
| how can fun2codes operator= code use push back while using the existing nodes to copy the data, surley you would wind up with two lots of the same list?? | |
|
|
|
| fun2code (1227) | ||||||
That was the intent.
We have actually reached a stopping point here. Further functions may be added as future exercises to extend functionality as desired. I suggest adding a node* back; as a data member of the list class so we don't have to iterate through the whole list to perform a push_back operation. Note: Our operator= is an expensive operation as we are iterating through the whole list with every call to push_back() there.If we would just remember the last node pushed back we would not have to do that. I suppose we could implement in just that function. Either way, I present a pop_back() here because even with a pointer to the back node we still have to iterate through the list. Why? We need a pointer to the next to last node. This will become the last node after the back node is popped and we must assign link = NULL for it. I have refined this over time. It used to be cumbersome. I think that I am finally handling the iterations below cleanly:
You now have a list which is basically functional, but is specialized to work only with nodes in which an integer, string pair is stored. This sort of limits its usefulness. You could rewrite all the member functions to work with a different node type, but that would get old quick. The next step would be to turn the list into a template class. You then define your int/string as a structure, add a couple of operator overloads (for < for instance, so that insert_asc() will work), then declare an instance of a list for your data type and you are good to go again. I think that going for all that in this thread would be a bit much though. Shall we summarize, handle questions, and then call it a wrap? EDIT: comments, adapting pop_back() to THIS list class | ||||||
|
Last edited on
|
||||||
| devonrevenge (897) | |
|
what we havnt done doubly linked lists yet!! nah just kidding, im in your debt fun2code you helped me loads, i have a lot to practice and understand, this is the best linked list tutorial on the net, seriously it proly is. im amazed that the operator= function means that when i use = to copy the things in main it goes about it differently, are their any other cases when i might want to change the use of =? could i change the value of say an int but only when i copy it with =? i cant think of a reason why i would want to, other than to see how it works, any other cases it might work? i havent done anything with templates, or std list, next subject i guess ***thanks fun2code*** self directed learning wouldnt have got me this far very quickly, i dont think i would have given up but i would have floundered so you have made my new coding hobby even better so thanks ^_^ it also seems to be fundemental to everything else i might want to learn, i looked at boost and winsock stuff, i say its a load of structs and linked lists, in (the form of templates too) i might be able to use them now, but nothing clever till i understand. | |
|
|
|
| naraku9333 (1038) | ||
| ||
|
|
||
| fun2code (1227) | ||||||
|
You're welcome for the help here devonrevenge. I think that linked lists make great learning exercises. They touch on a lot of elementary skills, and they aren't super hard so you can tinker with them casually. Like a good Lego model. The code for our list got scattered a bit back there, so I'll present the (hopefully) finished (ie properly working) class here. I added a couple of more "bonus" features (why not?) I added a node* back as a private data member. I have rewritten some member functions where back is involved, and to simplify where I could. The main() is setup to create 2 lists (chapter_1, chapter_2), then create a 3rd list wholeStory which is the "sum" of chapter_1 and chapter_2 I overloaded += in the myList class for this purpose. Also, I renamed the class myList to avoid naming conflicts. The name 'list' was asking for trouble here.
For testing:
Output:
| ||||||
|
|
||||||
| naraku9333 (1038) | |
|
@fun2code Maybe make the Node struct private? Also, since you add a back pointer in the class, why not add a second link in Node? I'm not a huge fan of the idea of the insert_asc function, it doesn't make sense to me unless the list is already sorted. I would also have just one data member (std::pair?), might be easier to covert to a template. Just my opinions/suggestions. @devonrevenge If you think this is fun, wait until you implement a binary search tree (BST). | |
|
Last edited on
|
|
| fun2code (1227) | |||||
|
@naraku9333 OK, easy ones first...
Two node*'s in the node structure? Would they be prev and next ? I didn't want to get into a doubly linked list here (just wrap this singly linked case). Were you thinking of something else?
Of course. The function is there in order to make it possible to create an ordered list. It would have to be used exclusively for adding nodes to the list.
I agree. The node with two separate data fields is devons design choice. I went with it because we were working on devonrevenge's list. At this point I would just go straight for a template class version. Now for the harder one...
The issue here for me is access to data in the list. Normally, when I'm tinkering with a list class I've written myself I will even (hold onto something) leave front public, so I may freely We probably want to do better than that here. Note that we presently have no access to the data in the list. We have no front() or back(). None of our member functions return a node pointer and front is private so there is no way to obtain a pointer to front in the main(). If we make the node structure private then this list is really on lockdown. I'd say that until we have fully functional iterator objects setup (which is beyond my skill level), the best we can do is to permit the use of nodes in the main(), provide a get_front() which returns a pointer to front by value NOT by reference (so the user cannot re assign front itself), and then warn the user not to mess with the values of link, which are exposed to him/her. Your thoughts? Q: So is that the primary difference beween an iterator into a list and a node*? An iterator exposes the data in a node, but hides the links? Another issue concerns any front() which might be written. It gets too convoluted due to there being two data fields in a node. ( would it be void front( int*& rpInt, string*& rpWord ) so we can change num and word in the node through these pointers? ) We'd probably be better off just working through node*'s for now. | |||||
|
Last edited on
|
|||||
| naraku9333 (1038) | |||
A proper iterator is essential for a functional list, and to be honest the one I made in school didn't implement an iterator (wasn't required) so I decided to make a new list attempting to replicate the std::list. I just finished (for the most part, need to debug more and implement reverse iterators) the iterator class.
As you can see I have it implemented basically just encapsulating the node. Now whether this is how the stl does it or the recommended way I'm not sure, as I said I'm new to implementing iterators myself. Heres the rest of the code in case your interested. I haven't implemented everything yet. Edit: Added reverse_iterator http://ideone.com/lN6NSA | |||
|
Last edited on
|
|||
| devonrevenge (897) | |
| woo thats way above my level, will come back in six months and tackle that | |
|
|
|
| fun2code (1227) | |||
|
@naraku9333. Thanks for that iterator code. I will tinker with iterators for the above class once I'm working with a template version. I have found various codes for an iterator class online. What I couldn't picture was how to create an object (iterator) which behaves entirely as though it is another type (pointer to T), without ever referring to it's data members. I see that this behavior is "teased out" through the creative definition of operators. Did you copy your operator-> correctly? It returns the same as operator* (namely T&). I found one operator-> definition for an iterator particularly interesting. Check this: this <--pointer to iterator *this <--- reference to iterator **this <--- reference to T (left * interpreted as our overload for * in iterator class) &(**this) <--- pointer to T Hence:
Also, I came across the real hardcore stuff. Here's a link to an article which explains how to define an iterator class so that it is fully compatible with the STL algorithms. ie, so you can call std::sort(), etc on your own containers. There are numerous typedefs, iterator "traits", and an inheritance heirarchy (where eg. iterator derives from const_iterator, etc,..). So, spoiler alert! Every detail for creating a singly linked list that is fully compatible with the standard STL methods is here: http://en.literateprograms.org/Singly_linked_list_%28C_Plus_Plus%29 @devonrevenge: Gets deep fast, huh? I'm only a couple of steps ahead of you. EDIT: Readers may wish to add front() and back() functions (both returning T&). The issue of what to return if the list is empty will arise. This issue is discussed in detail, and some valuable examples of exception handling code, can be found in this other thread (currently active in the general programming forum) http://www.cplusplus.com/forum/general/85346/ I have linked to the beginning of the thread. See pg. 2 re. above issues. | |||
|
Last edited on
|
|||
| naraku9333 (1038) | |
|
@fun2code Your'e right operator-> should return a pointer, nice catch I probably wouldn't have noticed that for a while. I may try to make the iterator compatible with std functions, but for now I just want to implement as much of std::list functionality for now. I want to be able to change std::list to sv::list in testing code and have them behave the same, which seems to be working (I've only done minimal testing). Latest version http://ideone.com/76GVqa | |
|
|
|
| devonrevenge (897) | |||
hey ive tried this a few times, declaring an array in a struct
whats the correct way to do it?? im gonna try and out put letters in a bigger array so i can use the linked list to display asci style art and animate it. all i think i will have to do is save a shape in each link say a letter and some how display each link side by side. i got an idea how to do it | |||
|
Last edited on
|
|||