C++ examples for Data Structure:Linked List
Merging Ordered Lists
#include <iostream> template <typename NODETYPE> class List;/*ww w. j a v a 2 s .c o m*/ 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; }; template <typename NODETYPE> ListNode<NODETYPE>::ListNode(const NODETYPE &info) : data(info), nextPtr(0) {} 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 &); void concatenate(List<NODETYPE> &); List<NODETYPE> merge(List<NODETYPE>&); bool isEmpty() const; void print() const; int size() const; private: ListNode<NODETYPE> *firstPtr; // pointer to first node ListNode<NODETYPE> *lastPtr; // pointer to last node int sz; ListNode<NODETYPE> *getNewNode(const NODETYPE &); }; template <typename NODETYPE> List<NODETYPE>::List() : firstPtr(0), lastPtr(0), sz(0) {} template <typename NODETYPE> List<NODETYPE>::~List() { if (!isEmpty()) { ListNode<NODETYPE> *currentPtr = firstPtr; while (currentPtr != 0) { ListNode<NODETYPE> *tempPtr = currentPtr; currentPtr = currentPtr->nextPtr; delete tempPtr; } } } 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; } ++sz; } 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; } ++sz; } // 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; --sz; return true; } } 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; --sz; return true; } } template <typename NODETYPE> void List<NODETYPE>::concatenate(List<NODETYPE> &listSecond) { ListNode<NODETYPE> *currentPtr = listSecond.firstPtr; while (currentPtr != 0) { insertAtBack(currentPtr->getData()); currentPtr = currentPtr->nextPtr; } } template<typename NODETYPE> List<NODETYPE> List<NODETYPE>::merge(List<NODETYPE>& list2){ List<NODETYPE> mergeList; ListNode<NODETYPE>* ptr1 = firstPtr; ListNode<NODETYPE>* ptr2 = list2.firstPtr; while (ptr1 != 0 && ptr2 != 0) { // values equal if (ptr1->getData() == ptr2->getData()) { mergeList.insertAtBack(ptr1->getData()); mergeList.insertAtBack(ptr2->getData()); ptr1 = ptr1->nextPtr; ptr2 = ptr2->nextPtr; } // second bigger if (ptr1->getData() < ptr2->getData()) { mergeList.insertAtBack(ptr1->getData()); ptr1 = ptr1->nextPtr; // bigger } else { mergeList.insertAtBack(ptr2->getData()); ptr2 = ptr2->nextPtr; } // end of lists if (ptr1 == 0) { mergeList.insertAtBack(ptr2->getData()); ptr2 = ptr2->nextPtr; } if (ptr2 == 0) { mergeList.insertAtBack(ptr1->getData()); ptr1 = ptr1->nextPtr; } } return mergeList; } template <typename NODETYPE> bool List<NODETYPE>::isEmpty() const { return firstPtr == 0; } template <typename NODETYPE> ListNode<NODETYPE> *List<NODETYPE>::getNewNode(const NODETYPE &value) { return new ListNode<NODETYPE>(value); } template <typename NODETYPE> void List<NODETYPE>::print() const { if (isEmpty()) { std::cout << "The list is empty\n\n"; return; } ListNode<NODETYPE> *currentPtr = firstPtr; while (currentPtr != 0) { std::cout << currentPtr->getData() << ' '; currentPtr = currentPtr->nextPtr; } } template <typename NODETYPE> int List<NODETYPE>::size() const { return sz; } #include <iostream> int main(int argc, const char* argv[]) { List<int> intList1; List<int> intList2; const int ARR_SIZE = 10; int data1[ARR_SIZE] = {1, 3, 5, 7, 8, 10, 12, 15, 17, 20}; int data2[ARR_SIZE] = {2, 4, 6, 9, 11, 13, 14, 16, 18, 19}; for (int i = 0; i < ARR_SIZE; ++i) { intList1.insertAtBack(data1[i]); intList2.insertAtBack(data2[i]); } std::cout << "Before Merge\nintList1 : "; intList1.print(); std::cout << "\nintList2 : "; intList2.print(); std::cout << std::endl; std::cout << "After Merge:\n"; List<int> mergeList = intList1.merge(intList2); mergeList.print(); std::cout << std::endl; return 0; }