The reason you always seem to be copying from head to tail is that your code is unkempt and tries to do the same thing in more than one way at once. If you try to copy from tail to head, you write the new list from tail to head and you read the old list from tail to head. These two cancel each other out. Think about it.
The reason you get compiler errors if you try to make the argument const
is that you're querying it with getTail()
and getHead()
, which you have not made const
.
EDIT:
Let's go back to the design and think about how tail-to-head copying should work. There are basically two ways to do it, read head-tail and write tail-to-head:
| |
v v
A-B-C-D A
| |
v v
A-B-C-D B-A
| |
v v
A-B-C-D C-B-A
| |
v v
A-B-C-D D-C-B-A
or vise-versa:
| |
v v
A-B-C-D D
| |
v v
A-B-C-D D-C
| |
v v
A-B-C-D D-C-B
| |
v v
A-B-C-D D-C-B-A
Bur if we try to do both, they cancel out:
| |
v v
A-B-C-D D
| |
v v
A-B-C-D C-D
| |
v v
A-B-C-D B-C-D
| |
v v
A-B-C-D A-B-C-D
All we have to do is choose one. If we choose the first one, we change the copy ctor:
curr = list.getHead(); // curr points to list head.
cout << "Reading from head-to-tail...\n" << endl;
while(curr) {
...
append(stuPtr); // append the node with stuPtr to head or tail of list.
curr = curr->getNext();
} // end while*/
And it works. If we choose the second, we leave the ctor alone and change append(...)
:
if(isEmpty()) { // tail=NULL, no list.
cout << "List is empty. Inserting first Node.\n" << endl;
head = newNode;
tail = newNode; // new Node becomes head & tail.
} else {
tail->setNext(newNode); // NEXT ptr of tail points to newNode.
newNode->setPrev(tail); // newNode's PREV points to former tail.
tail = newNode; // newNode becomes the new tail.
} // end if/else
Generally speaking, the way to avoid problems like this is to start small and simple, add complexity a little at a time, test at every step, test new features in isolation first, and never add to code that doesn't work. The way to find non-obvious bugs is to take your code and simplify, removing complexity piecemeal until you reach the simplest version that still exhibits the buggy behavior-- or more likely the bug becomes obvious along the way.