0

I call a function interleave that looks like

void AddressLinkedList::interleave(AddressLinkedList& other) {
    AddressLinkedList temp;
    AddressListNode* thisCur = this->head;
    AddressListNode* otherCur = other.head;
    for (int i = 0; i < this->length + other.length; i++) {
        if (i % 2 == 0) {
            temp.insertEnd(thisCur->data);
            thisCur = thisCur->next;
        }
        else if (i % 2 != 0) {
            temp.insertEnd(otherCur->data);
            otherCur = otherCur->next;
        }
    }
    return;
}

This function is supposed to interweave a singly linked list A with a singly linked list B along the lines of if A looked like "1, 2, 3" and B looked like "4, 5, 6", then the call linkedListA.interleave(linkedListB) should make A "1, 4, 2, 5, 3, 6". I've successfully managed to create a list like this, the problem is it that it's the temp list, but I don't know how to make it so it would be the this pointer with an end goal linkedListA be the aforementioned "singly linked list A". In case it matters, below is the overloaded assignment operator and the insertEnd function.

void AddressLinkedList::insertEnd(const Address& value) {
    if (length == 0) {
        this->insertStart(value);
        return;
    }
    AddressListNode* temp = new AddressListNode(value);
    length++;
    tail->next = temp;
    tail = temp;
}
AddressLinkedList& AddressLinkedList::operator=(const AddressLinkedList& other) {
    delete this;
    AddressListNode* current;
    current = other.head;
    while (current != nullptr) {
        insertEnd(current->data);
        current = current->next;
    }
    return *this;
}
  • What about the list B? Shall it be empty after the executing the function? – Vlad from Moscow May 03 '20 at 22:59
  • It's fine for list B to still have items in it. –  May 03 '20 at 23:00
  • When why is not the parameter a constant reference? – Vlad from Moscow May 03 '20 at 23:01
  • It might just be an error with the starting function declarations our instructor gave us, the assignment explicitly stated you do not have to remove items from ```other``` –  May 03 '20 at 23:05
  • *"it's the temp list, but I don't know how to make it so it would be the this pointer"* -- this is worded strangely. I think you mean "it's the temp list, but I don't know how to make it so it would be `*this`", since the object to which `this` points is the current object. (This is related to the reason why `delete this;` is absolutely wrong in your assignment operator. If you were to delete the object that is supposed to receive the assignment, you no longer have an object to receive the assignment.) – JaMiT May 03 '20 at 23:21
  • What tools have you created so far for `AddressLinkedList`? If you have a `swap` function, your answer would be almost trivial. (Assignment should also work -- if the implementation is fixed -- but copy assignment is a bit wasteful. Do you have move assignment?) – JaMiT May 03 '20 at 23:27

1 Answers1

0

Since interleave is defined as a member function of AddressLinkedList it should modify (and work on) the object it was called on. So you don't need to (and you shouldn't) create a temporary list to use it to build your resulting collection and then "assign" it as this. It is possible with some new, delete and raw pointer trickery, but I wouldn't recommend this (the idea would be to create AddressListNode* as head and then assign that new head where the original one was, but you would also had to delete previous chain of AddressListNode* from original head to avoid memory leaks, as I said, not recommended).

Assuming that your code that calls this method looks like this:

AddressLinkedList A;
AddressLinkedList B;
... //inserting values to A and B
A.interleave(B);

Your interleave implementation should looks more like this (it's more of a proof on concept, than working solution, I didn't compiled it):

void AddressLinkedList::interleave(AddressLinkedList& other) {
    AddressListNode* thisCur = head;
    AddressListNode* otherCur = other.head;
    while (thisCur != nullptr) { //assumig that last node points to nullptr
        AddressListNode* nextNode = thisCur->next;
        AddressListNode* otherNext = otherCur->next;
        thisCur->next = otherCur; //attach it to node from other
        thisCur = thisCur->next; //advance to next node
        thisCur = nextNode; //reattach node that was originally after current
        thisCur = thisCur->next; //advance again to next node
        otherCur = otherNext ; //advance on other
    }
    other->head = nullptr; //loop above hijack nodes from other
}

All this code do is, it takes heads of both of your collection, iterate over this and for every node it attaches corresponding node from other. Effectively it will modify your object on which you originally called interleave method. However due to modifying AddressListNode pointer it will also destroy your original AddressLinkedList you passed as and argument to interleave. So you should probably modify it in a way that for thisCur->next = otherCur; actually create a copy of an Address and create new node.

NRUB
  • 404
  • 4
  • 17
  • When I ran this, for some reason after ```this->head``` it made list A "1, 4, 5, 6", attaching ```otherCur``` after list A's ```head`` every time instead of interweaving them. –  May 04 '20 at 06:14
  • Don't want to be that one mean guy, but as I said this is more of a proof of concept. This is your assignment after all, so attach debugger, go step by step, and find where the issue is. I'm just trying to point you in the right direction. And keep in mind that what I wrote as example IS the correct way to do this. – NRUB May 04 '20 at 06:19
  • I fixed a bug in my example, now it should work correctly. However it still hijacks nodes from `other`, you should instead create proper nodes and assign `Address` to them, similar to how it's done in `insertEnd`. – NRUB May 04 '20 at 06:45