I have the solution code here:
// Pre-condition: The fronts of two linked lists are provided.
// Post-condition: A linked list is returned that is the result of
// interleaving the elements from each provided list.
// (e.g. {1, 2, 3} & { 4, 5, 6} would return {1, 4, 2, 5, 3, 6}
Node* interleave( Node*& front1, Node*& front2 ) {
if( !front1 ) return front2;
if( !front2 ) return front1;
Node* third = front1->next; //this will become the third element
Node* fourth = front2->next; // this will be come the fourth element
front1->next = front2;
front2->next = third;
third = interleave(third, fourth);
return front1;
}
I kind of understand it but i would never be able to come up with something like this since i'm very bad at recursion. Is there another way to do this problem non-recursively? if so could you give me a hint? I tried this:
Node* interleave( No开发者_运维技巧de*& front1, Node*& front2 ) {
Node* newNode = new Node;
while(front1!=NULL && front2!=NULL){
newNode = front1->next;
newNode = front2->next;
front1 = front1->next;
front2 = front2->next;
}
return newNode;
}
I'm sure it's wrong but that's the only thing i can come up with right now. Please help. Thank you
Try drawing two linked lists in parallel on a sheet of paper. Put some numbers in the nodes, just to tell them apart. Consider how you would reconnect them to form a single list, starting at the head (or "front") and working down. Note that you have to keep track of a few special nodes, like the first node of the resultant list and a couple of others. The pattern should become clear.
(Note that there's no need to construct a new node with new
.)
There are a few mistakes in your code:
Node* interleave( Node*& front1, Node*& front2 )
I don't see the need for a reference to a pointer, since the first item in front1 will keep on being the first, and you don't need to mess with front2 at all.
Node* newNode = new Node;
while(front1!=NULL && front2!=NULL){
newNode = front1->next;
This is causing a memory leak - you're allocating at least sizeof(Node) bytes, but then you're losing the reference to the pointer, and you won't be able to delete it anymore. Also, you're not doing anything with newNode, so you might throw it away as well.
front1 = front1->next;
front2 = front2->next;
Basically you're telling that front1 will rather point to the next element, and since you passed a reference to front1, you're altering the real pointer. Eventually, front1 or front2 will be NULL and the loop will terminate, so at least one of the two given parameters will become useless. You're never changing next, so the order will be left unchanged - you're just walking through the lists.
One approach could be to set front2's value to front1->next, then swap pointers and iterate again:
Node *a = front1, *b = front2;
while (a && b) {
Node* tmp = a->next;
a->next = b;
b = tmp;
a = a->next;
}
return front1;
I didn't test this, but it should be close to working. You can replace the verbose swap code with std::swap() if you're using stl. The idea is simple: suppose you have two lists:
A -> B -> C -> NULL
D -> E -> F -> NULL
you say that A's next item is going to be the first element in the second list, so D:
A -> D -> E -> F -> NULL
and then the second lists becomes the ancient A's successor, so just B -> C -> NULL. You then advance a to point to its new next, or D, so you now have:
D -> E -> F -> NULL
B -> C -> NULL
and you repeat:
D -> B -> C -> NULL
E -> F -> NULL
B -> C -> NULL
F -> NULL
and so on until a NULL is met. Then front1, that still points to A, should have the right sequence (that is, unless I'm terribly wrong :p )
精彩评论