Thread: Linked List

Hybrid View

Previous Post Previous Post   Next Post Next Post
  1. #1
    printf("Hello Cboard\n"); codeprada's Avatar
    Join Date
    Jan 2011
    Location
    In a little room at the back of your brain
    Posts
    68

    Linked List

    was bored at work so i decided to implement a linked list. tell me what u think....all criticism is welcomed. i'm here to learn it does not have every single method. (wasn't that bored). oh and i want to know if there's a way u can avoid writing template<class T> before every method besides using define. below is just the class.


    Code:
    template <class T>
    class LinkedList
    {
    private:
        struct node {
            T data;
            struct node * next,
                        * prev;
        };
        T getDataAtNode(int index);
        struct node * head,
                    * end;
    
    public:
        LinkedList();
        LinkedList(T data);
        void push(T data);
        T pop();
        T operator[](int index);
        bool isEmpty();
        void clear();
        int length();
    };
    
    template <class T>
    T LinkedList<T>::getDataAtNode(int index)
    {
        int c = 0; struct node * iter = head;
        while(iter)
        {
            if (c++ == index)
                return iter->data;
            iter = iter->next;
        }
        return NULL;
    
    }
    
    template <class T>
    LinkedList<T>::LinkedList()
    {
        head = new node();
        head->data = NULL;
        head->next = NULL;
        head->prev = NULL;
        end = head;
    }
    
    template <class T>
    LinkedList<T>::LinkedList(T data)
    {
        if (head != end)
        {
            head = new node();
            end = head;
        }
    
        head->data = data;
        head->next = NULL;
        head->prev = NULL;
    
    }
    
    template <class T>
    T LinkedList<T>::operator[](int index)
    {
        return (getDataAtNode(index));
    }
    
    template <class T>
    void LinkedList<T>::push(T data)
    {
        if(head->data == NULL)
        {
            head->data = data;
        }
        else {
            struct node * new_node = new node();
            new_node->data = data;
            new_node->next = NULL;
            new_node->prev = end;
            end->next = new_node;
            end = new_node;
        }
    }
    
    template <class T>
    T LinkedList<T>::pop()
    {
        T data = end->data;
        if(end->prev)
        {
            end = end->prev;
        }
        else
        {
            end = head;
            head->data = NULL;
        }
        end->next = NULL;
        return data;
    }
    
    template <class T>
    bool LinkedList<T>::isEmpty()
    {
        return (head->data == NULL && head == end ? true : false);
    }
    
    template <class T>
    void LinkedList<T>::clear()
    {
        end = head;
        head->data = NULL;
        head->next = NULL;
    }
    
    template <class T>
    int LinkedList<T>::length()
    {
        int c = 0; struct node * iter = head;
        while(iter)
        {
            c++;
            iter = iter->next;
        }
        return c;
    }
    We shouldn't be quick to criticize unless we can do better.
    Code:
    public function __clone() { die ( "I'm one of a kind" ); }

  2. #2
    Programming Wraith GReaper's Avatar
    Join Date
    Apr 2009
    Location
    Greece
    Posts
    2,738
    * Define them in the class declaration.
    * Make a macro...
    * Don't use templates!
    Devoted my life to programming...

  3. #3
    printf("Hello Cboard\n"); codeprada's Avatar
    Join Date
    Jan 2011
    Location
    In a little room at the back of your brain
    Posts
    68
    Quote Originally Posted by Sipher View Post
    * Define them in the class declaration.
    * Make a macro...
    * Don't use templates!
    what's so bad about templates?
    We shouldn't be quick to criticize unless we can do better.
    Code:
    public function __clone() { die ( "I'm one of a kind" ); }

  4. #4
    Programming Wraith GReaper's Avatar
    Join Date
    Apr 2009
    Location
    Greece
    Posts
    2,738
    Quote Originally Posted by codeprada View Post
    what's so bad about templates?
    Nothing, nothing! I was just joking!...
    Devoted my life to programming...

  5. #5
    printf("Hello Cboard\n"); codeprada's Avatar
    Join Date
    Jan 2011
    Location
    In a little room at the back of your brain
    Posts
    68
    Quote Originally Posted by Sipher View Post
    Nothing, nothing! I was just joking!...
    lol oh... i'll add something like a cursor, a next() and previous() function....maybe
    We shouldn't be quick to criticize unless we can do better.
    Code:
    public function __clone() { die ( "I'm one of a kind" ); }

  6. #6
    'Allo, 'Allo, Allo
    Join Date
    Apr 2008
    Posts
    639
    There's a whole bunch of allocating, don't see no freeing.

  7. #7
    Lurking whiteflags's Avatar
    Join Date
    Apr 2006
    Location
    United States
    Posts
    9,612
    >> oh and i want to know if there's a way u can avoid writing template<class T> before every method

    Define all of the methods inside of the class.

    Also, provide iterators, and provide assignment and copying, at least.

  8. #8
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    Avoiding writing template: write the code inline in the class.
    Suggestions:
    Use typename instead of class.
    Use std::shared_ptr and std::weak_ptr.
    Use nullptr instead of NULL.
    Drop the "struct" on the pointers.
    Problems:
    Not freeing memory!
    Class suffers from raw pointer issues (http://sourceforge.net/apps/mediawik...pointer_issues)
    Quote Originally Posted by Adak View Post
    io.h certainly IS included in some modern compilers. It is no longer part of the standard for C, but it is nevertheless, included in the very latest Pelles C versions.
    Quote Originally Posted by Salem View Post
    You mean it's included as a crutch to help ancient programmers limp along without them having to relearn too much.

    Outside of your DOS world, your header file is meaningless.

  9. #9
    C++ Junkie Mozza314's Avatar
    Join Date
    Jan 2011
    Location
    Australia
    Posts
    174
    Don't implement operator[] - linked list are not for random access, it's inefficient to have to traverse an average of half the list to get an element out.

    You should keep track of the size of the list as you add and remove elements so that when you call length() you can return a number straight away. Traversing the list just for this is extremely inefficient!

    Implement a copy constructor and operator= or make them private to avoid accidental shallow copying.

    Quote Originally Posted by Elysia View Post
    Suggestions:
    Use std::shared_ptr and std::weak_ptr.
    Problems:
    Class suffers from raw pointer issues
    While I generally agree with the idea of using smart pointers over raw pointers, I think a fundamental utility like this deserves to not have the overhead of smart pointers.

  10. #10
    Algorithm Dissector iMalc's Avatar
    Join Date
    Dec 2005
    Location
    New Zealand
    Posts
    6,318
    Quote Originally Posted by Mozza314 View Post
    Don't implement operator[] - linked list are not for random access, it's inefficient to have to traverse an average of half the list to get an element out.
    Finally, someone else who points out this kind of thing! I wholeheartedly agree.

    You should keep track of the size of the list as you add and remove elements so that when you call length() you can return a number straight away. Traversing the list just for this is extremely inefficient!
    GCC actually walks the list to get the size. The reason that some implementations do and some don't is that there is a trade off between constant time size() and linear time splice() vs linear time size() and constant time splice(). Can't do both in constant time.


    C++ has the notion that you only pay for what you use. If you don't need a smart pointer in there then you should not be forced to. Simply allow the user of the class to use a smart pointer as their templated type.

    Or you mean as the links themselves? That's actually not a good idea. If you utilised that to automatically delete the whole list by deleting just the first node say, then you end up with a recursive delete and could blow the stack, for example.
    In a list, nodes don't own subsequent nodes. It's just a sequence. Enforcing some kind of ownership semantics where it doesn't belong is just wrong.
    Last edited by iMalc; 02-23-2011 at 12:23 PM.
    My homepage
    Advice: Take only as directed - If symptoms persist, please see your debugger

    Linus Torvalds: "But it clearly is the only right way. The fact that everybody else does it some other way only means that they are wrong"

  11. #11
    C++ Junkie Mozza314's Avatar
    Join Date
    Jan 2011
    Location
    Australia
    Posts
    174
    Quote Originally Posted by iMalc View Post
    GCC actually walks the list to get the size. The reason that some implementations do and some don't is that there is a trade off between constant time size() and linear time splice() vs linear time size() and constant time splice(). Can't do both in constant time.
    I actually learned about this complication just the other day flicking through Scott Meyers' "Effective STL". Really makes the point that you should never do

    Code:
    someList.size() == 0
    since that can be linear time and you have the perfectly appropriate empty() function you can use instead.

    Of course, if you're not implementing splice(), size() should be constant time.

    I just took a look at the GNU STL implementation. I'm somewhat shocked that it always traverses the list to do size(), I thought at least it would return a known size when it could. I suppose there is an overhead to doing that, but surely it's minimal. I definitely won't be calling list::size() without giving it a second thought from now on.

  12. #12
    Algorithm Dissector iMalc's Avatar
    Join Date
    Dec 2005
    Location
    New Zealand
    Posts
    6,318
    Quote Originally Posted by Mozza314 View Post
    I actually learned about this complication just the other day flicking through Scott Meyers' "Effective STL". Really makes the point that you should never do

    Code:
    someList.size() == 0
    since that can be linear time and you have the perfectly appropriate empty() function you can use instead.
    I find myself reasonably often bringing this up in code reviews or running into it in older code. Other's at work only use Microsoft's compilers, and simply don't know that the difference can be quite important if you're writing portable code.
    My homepage
    Advice: Take only as directed - If symptoms persist, please see your debugger

    Linus Torvalds: "But it clearly is the only right way. The fact that everybody else does it some other way only means that they are wrong"

  13. #13
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    Overhead is negligible. Change it if and only if performance suffers.
    Quote Originally Posted by Adak View Post
    io.h certainly IS included in some modern compilers. It is no longer part of the standard for C, but it is nevertheless, included in the very latest Pelles C versions.
    Quote Originally Posted by Salem View Post
    You mean it's included as a crutch to help ancient programmers limp along without them having to relearn too much.

    Outside of your DOS world, your header file is meaningless.

  14. #14
    Lurking whiteflags's Avatar
    Join Date
    Apr 2006
    Location
    United States
    Posts
    9,612
    Even if performance suffers, I would suck it up. The only differences between a regular pointer and a weak pointer are that the weak one can transfer ownership of the pointee to a reference counted pointer if you ask it to. Since weak pointers aren't doing anything regular pointers don't, the overhead is actually paid at compile time. (From all the template code.) Actually, I should say that weak pointers are probably not the source of performance problems.
    Last edited by whiteflags; 02-22-2011 at 05:16 PM.

  15. #15
    C++ Junkie Mozza314's Avatar
    Join Date
    Jan 2011
    Location
    Australia
    Posts
    174
    Quote Originally Posted by whiteflags View Post
    Even if performance suffers, I would suck it up. The only differences between a regular pointer and a weak pointer are that the weak one can transfer ownership of the pointee to a reference counted pointer if you ask it to. Since weak pointers aren't doing anything regular pointers don't, the overhead is actually paid at compile time. (From all the template code.) Actually, I should say that weak pointers are probably not the source of performance problems.
    Hmmm, it would be an interesting experiment to, say, run a script through all of an stl implementation to replace all the raw pointers with weak pointers (probably a custom version of weak pointer to wrap pointer arithmetic and such as well) and then to a comparison with some stl intensive code.
    Last edited by Mozza314; 02-23-2011 at 02:33 AM.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. C++ Linked list program need help !!!
    By dcoll025 in forum C++ Programming
    Replies: 1
    Last Post: 04-20-2009, 10:03 AM
  2. Following CTools
    By EstateMatt in forum C Programming
    Replies: 5
    Last Post: 06-26-2008, 10:10 AM
  3. Reverse function for linked list
    By Brigs76 in forum C++ Programming
    Replies: 1
    Last Post: 10-25-2006, 10:01 AM
  4. Template Class for Linked List
    By pecymanski in forum C++ Programming
    Replies: 2
    Last Post: 12-04-2001, 09:07 PM
  5. singly linked list
    By clarinetster in forum C Programming
    Replies: 2
    Last Post: 08-26-2001, 10:21 PM