C++ examples for Data Structure:Linked List
Create a linked list
#include <iostream> #include <string> // forward declaration of class List template <typename NODETYPE> class List;/*from w w w . j a v a 2 s.c om*/ template <typename NODETYPE> class ListNode { friend class List<NODETYPE>; // make List a friend public: explicit ListNode(const NODETYPE &); NODETYPE getData() const; private: NODETYPE data; ListNode<NODETYPE> *nextPtr; }; // constructor template <typename NODETYPE> ListNode<NODETYPE>::ListNode(const NODETYPE &info) : data(info), nextPtr(0) {} // return copy of data in node template <typename NODETYPE> NODETYPE ListNode<NODETYPE>::getData() const { return data; } template <typename NODETYPE> class List { public: List(); ~List(); void insertAtFront(const NODETYPE &); void insertAtBack(const NODETYPE &); bool removeFromFront(NODETYPE &); bool removeFromBack(NODETYPE &); bool isEmpty() const; void print() const; private: ListNode<NODETYPE> *firstPtr; // pointer to first node ListNode<NODETYPE> *lastPtr; // pointer to last node // utility function to allocate new node ListNode<NODETYPE> *getNewNode(const NODETYPE &); }; // default constructor template <typename NODETYPE> List<NODETYPE>::List() : firstPtr(0), lastPtr(0) {} // destructor template <typename NODETYPE> List<NODETYPE>::~List() { if (!isEmpty()) { std::cout << "Destroying Nodes...\n"; ListNode<NODETYPE> *currentPtr = firstPtr; // delete remaining nodes while (currentPtr != 0) { ListNode<NODETYPE> *tempPtr = currentPtr; std::cout << tempPtr->data << '\n'; currentPtr = currentPtr->nextPtr; delete tempPtr; } } } // insert Node at front of list template <typename NODETYPE> void List<NODETYPE>::insertAtFront(const NODETYPE &value) { ListNode<NODETYPE> *newPtr = getNewNode(value); if (isEmpty()) firstPtr = lastPtr = newPtr; // new list only has one node else { newPtr->nextPtr = firstPtr; // point new node to previous list node firstPtr = newPtr; } } // insert node at back of list template <typename NODETYPE> void List<NODETYPE>::insertAtBack(const NODETYPE &value) { ListNode<NODETYPE> *newPtr = getNewNode(value); if (isEmpty()) firstPtr = lastPtr = newPtr; // new list has only one node else { lastPtr->nextPtr = newPtr; lastPtr = newPtr; } } // delete node from front of list template <typename NODETYPE> bool List<NODETYPE>::removeFromFront(NODETYPE &value) { if (isEmpty()) // list is empty return false; else { ListNode<NODETYPE> *tempPtr = firstPtr; if (firstPtr == lastPtr) firstPtr = lastPtr = 0; // no nodes remain after removal else firstPtr = firstPtr->nextPtr; // point to previous 2nd node value = tempPtr->data; delete tempPtr; return true; } } // delete node from back of list template <typename NODETYPE> bool List<NODETYPE>::removeFromBack(NODETYPE &value) { if (isEmpty()) // list is empty return false; else { ListNode<NODETYPE> *tempPtr = lastPtr; if (firstPtr == lastPtr) // list has one element firstPtr = lastPtr = 0; // no nodes remain after removal else { ListNode<NODETYPE> *currentPtr = firstPtr; // locate second to last element while (currentPtr->nextPtr != lastPtr) currentPtr = currentPtr->nextPtr; // move to next node lastPtr = currentPtr; // remove last node currentPtr->nextPtr = 0; // this is now the last node } value = tempPtr->data; delete tempPtr; return true; } } // is List empty template <typename NODETYPE> bool List<NODETYPE>::isEmpty() const { return firstPtr == 0; } // return pointer to newly allocated node template <typename NODETYPE> ListNode<NODETYPE> *List<NODETYPE>::getNewNode(const NODETYPE &value) { return new ListNode<NODETYPE>(value); } // display contents of List template <typename NODETYPE> void List<NODETYPE>::print() const { if (isEmpty()) { std::cout << "The list is empty\n\n"; return; } ListNode<NODETYPE> *currentPtr = firstPtr; std::cout << "The list is: "; while (currentPtr != 0) { std::cout << currentPtr->data << ' '; currentPtr = currentPtr->nextPtr; } std::cout << "\n\n"; } // display program instructions to user void instructions() { std::cout << "Enter one of the following:\n" << " 1 to insert at beginning of list\n" << " 2 to insert at end of list\n" << " 3 to delete from beginning of list\n" << " 4 to delete from end of list\n" << " 5 to end list processing\n"; } // function to test a list template <typename T> void testList(List<T> &listObject, const std::string &typeName) { std::cout << "Testing a List of " << typeName << " values\n"; instructions(); int choice; T value; do { std::cout << "? "; std::cin >> choice; switch (choice) { case 1: std::cout << "Enter " << typeName << ": "; std::cin >> value; listObject.insertAtFront(value); listObject.print(); break; case 2: std::cout << "Enter " << typeName << ": "; std::cin >> value; listObject.insertAtBack(value); listObject.print(); break; case 3: if (listObject.removeFromFront(value)) std::cout << value << " removed from list\n"; listObject.print(); break; case 4: if (listObject.removeFromBack(value)) std::cout << value << " removed from list\n"; listObject.print(); break; } } while (choice < 5); std::cout << "End list test\n\n"; } int main(int argc, const char *argv[]) { List<int> integerList; testList(integerList, "integer"); List<double> doubleList; testList(doubleList, "double"); return 0; }