Jump to content

C++ Linked Lists Etiquette Question

Go to solution Solved by Nineshadow,

Templates. Make a linked list class template, and use one with a suitable structure.

Hi guys, I was working on a project for class that includes the prereqs:

  • Create a linked list of employee numbers  and their salaries.
  • Have an add function, remove function(removes the last node), and a display and a clear function.

I thought, at first, I should create one linked list for the employee numbers and another for the salaries. But then I thought It would be easier to make a linked list that instead of just a data and *next.... I could have a data1 and a data2 and then a *next. But then I considered it to be possibly bad programming, as functions and classes should be flexible. Can you guys with more programming experience let me know which method I should go with? Thanks

 

Link to comment
https://linustechtips.com/topic/579359-c-linked-lists-etiquette-question/
Share on other sites

Link to post
Share on other sites

Templates. Make a linked list class template, and use one with a suitable structure.

i5 4670k @ 4.2GHz (Coolermaster Hyper 212 Evo); ASrock Z87 EXTREME4; 8GB Kingston HyperX Beast DDR3 RAM @ 2133MHz; Asus DirectCU GTX 560; Super Flower Golden King 550 Platinum PSU;1TB Seagate Barracuda;Corsair 200r case. 

Link to post
Share on other sites

Do like @Nineshadow said. Just make sure you don't mess up your equality operators. And keep in mind that C++ is statically compiled, that means each variant of structure use with that template has to be compiled separately, this messes up code encapsulation somewhat, you will need to put all the template code in a header file.

Link to post
Share on other sites

This is my implementation of a (double) linked list template :

template <class T>
class List
{
    struct Node
    {
        T data;
        Node *prev;
        Node *next;
    };
    Node *head;
    Node *tail;
public:
    struct Iterator
    {
    private:
        Node *node;
    public:
        friend class List;
        Iterator()
        {
            node = NULL;
        }
        Iterator(Node *n)
        {
            node = n;
        }
        T& operator*() const
        {
            if(node!=NULL) return node->data;
            else throw "Null operator";
        }
        Iterator& operator++()
        {
            if(node->next==NULL)node=NULL; //throw "Iterator out of bounds";
            else {
            node=node->next;
            return *this;
            }
        }
         Iterator operator++(int)
        {
            if(node->next==NULL)node=NULL ;//throw "Iterator out of bounds";
            else {
            Iterator temp = *this;
            ++(*this);
            return temp;
            }
        }
        Iterator& operator--()
        {
            if(node->prev==NULL)node=NULL ;//throw "Iterator out of bounds";
            else {
            node = node->prev;
            return *this;
            }
        }
        Iterator operator--(int)
        {
            if(node->prev==NULL)node=NULL ;//throw "Iterator out of bounds";
            else {
            Iterator temp = *this;
            --(*this);
            return temp;
            }
        }
        bool operator==(const Iterator& it) const
        {
            if(it.node == this->node)return true;
            else return false;
            }
        bool operator!=(const Iterator& it) const
        {
            if(!(it==*this)) return true;
            else return false;
            }
    };
    bool isEmpty()
    {
        return head ==NULL;
    }
    List()
    {
        head=tail=NULL;
    }
    ~List()
    {
        if(!isEmpty()) clear();
        }
    void clear()
    {
        Node *i = head, *temp;
        while(i!=NULL)
        {
            temp = i;
            i=i->next;
            delete temp;
        }
        head=tail=NULL;
    }
    Iterator end() const
    {
        return Iterator(tail);
    }
    Iterator front() const
    {
        return Iterator(head);
    }
    void pop_back()
    {
        if(isEmpty()) throw "Empty List";
        else if(head==tail) delete head;
        else
        {
            Node *temp = tail->prev;
            delete tail;
            temp->next = NULL;
            tail=temp;
        }
    }
    void pop_front()
    {
        if(isEmpty()) throw "Empty List";
        else if(head==tail) delete head;
        else
        {
            Node *temp = head->next;
            delete head;
            temp->prev = NULL;
            head=temp;
        }
    }
    void remove(Iterator it)
    {
        if(isEmpty()) throw "Empty List";
        else if(head==tail)
        {
            delete head;
            head = tail = NULL;
            return;
        }
        else if(it==this->end())
            pop_back();
        else if(it==this->front())
            pop_front();
        else
        {
            it.node->prev->next = it.node->next;
            it.node->next->prev = it.node->prev;
            delete it.node;
        }

    }
    void push_back(T value)
    {
        if(isEmpty())
        {
            head = new Node;
            head->data = value;
            head->next=NULL;
            head->prev=NULL;
            tail=head;
        }
        else
        {
            Node *newNode = new Node;
            newNode->data = value;
            newNode->next=NULL;
            newNode->prev=tail;
            tail->next=newNode;
            tail=newNode;
        }
    }
    void push_front(T value)
    {
        if(isEmpty())
        {
            head = new Node;
            head->data = value;
            head->next=NULL;
            head->prev=NULL;
            tail=head;
        }
        else
        {
            Node *newNode = new Node;
            newNode->data = value;
            newNode->prev=NULL;
            newNode->next=head;
            head->prev=newNode;
            head=newNode;
        }
    }
    void swap(Iterator node1, Iterator node2)
    {
        T temp = node1.node->data;
        node1.node->data = node2.node->data;
        node2.node->data=temp;
    }
    void insert_before(T value, Iterator it)
    {
        Node *newNode = new Node;
        newNode->data = value;
        it.node->prev->next = newNode;
        newNode->prev=it.node->prev;
        it.node->prev=newNode;
        newNode->next=it.node;
    }
    void insert_after(T value, Iterator it)
    {
        Node *newNode = new Node;
        newNode->Data = value;
        newNode->prev=it.node;
        newNode->next=it.node->next;
        it.node->next->prev=newNode;
        it.node->next=newNode;
    }
};

In your case you would first create a structure, something like this :

struct employee{
    unsigned int id;
    float salary;
};

Then use a linked list class template like this :

List<employee> list;
/*
  etc...
  etc...
*/

 

 

i5 4670k @ 4.2GHz (Coolermaster Hyper 212 Evo); ASrock Z87 EXTREME4; 8GB Kingston HyperX Beast DDR3 RAM @ 2133MHz; Asus DirectCU GTX 560; Super Flower Golden King 550 Platinum PSU;1TB Seagate Barracuda;Corsair 200r case. 

Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

×