Merging Ordered Lists - C++ Data Structure

C++ examples for Data Structure:Linked List

Description

Merging Ordered Lists

Demo Code

#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;
}

Result


Related Tutorials