I don't understand the reversal of the list of a node l
in a binomial heap:
Node* reverseList(Node* l) {
//return reverseNode(l);
if(l->sibling)
{
return reverseList(l->sibling);
l->sibling->sibling = l;
}
}
What does this mean? :
l->sibling->sibling = l;
The parent?
A return
statement ends the execution of the function, so you are asking about dead code.
I would expect the function to actually be like this:
Node* reverseList(Node* l) {
if (l->sibling)
{
Node* head = reverseList(l->sibling);
l->sibling->sibling = l;
l->sibling = NULL;
return head;
}
return l;
}
To visualise this, let an example linked list consist of three nodes:
l
↓
┌───────────────┐ ┌───────────────┐ ┌───────────────┐
│ sibling: ─────────► │ sibling: ─────────► │ sibling: NULL │
│ │ │ │ │ │
└───────────────┘ └───────────────┘ └───────────────┘
When the function is called, we get into the if
and make a recursive call. That new (second) execution context has its own local variables, and to distinguish them, I will add an accent to their names. So we have another l'
variable:
l l'
↓ ↓
┌───────────────┐ ┌───────────────┐ ┌───────────────┐
│ sibling: ─────────► │ sibling: ─────────► │ sibling: NULL │
│ │ │ │ │ │
└───────────────┘ └───────────────┘ └───────────────┘
Also that function's execution will make a recursive call:
l l' l"
↓ ↓ ↓
┌───────────────┐ ┌───────────────┐ ┌───────────────┐
│ sibling: ─────────► │ sibling: ─────────► │ sibling: NULL │
│ │ │ │ │ │
└───────────────┘ └───────────────┘ └───────────────┘
The latest (third) execution of the function gets l'->sibling
as argument and will assign that to its own local variable l"
. It will find that l"->sibling
is NULL
, and so it just returns the same pointer without making any alteration. At this moment the lifetime of the variable l"
ends. The caller assigns the returned value to a local head'
variable -- again the accent to make clear this happens in the second execution context:
l l'
↓ ↓
┌───────────────┐ ┌───────────────┐ ┌───────────────┐
│ sibling: ─────────► │ sibling: ─────────► │ sibling: NULL │
│ │ │ │ │ │
└───────────────┘ └───────────────┘ └───────────────┘
↑
head'
Now we get to the statement: l'->sibling->sibling = l'
. That means an assignment is made to the sibling
member of the last node, and so we get:
l l'
↓ ↓
┌───────────────┐ ┌───────────────┐ ┌───────────────┐
│ sibling: ─────────► │ sibling: ─────────► │ sibling: ─┐ │
│ │ │ │ ◄───────────────┘ │
└───────────────┘ └───────────────┘ └───────────────┘
↑
head'
Then we execute l'->sibling = NULL
:
l
↓
┌───────────────┐ ┌───────────────┐ ┌───────────────┐
│ sibling: ─────────► │ sibling: NULL │ │ sibling: ─┐ │
│ │ │ │ ◄───────────────┘ │
└───────────────┘ └───────────────┘ └───────────────┘
↑
head'
Then we execute return head'
. The variables of the second execution context end their lives (no more accents). The first execution context will assign the returned pointer to its own head
variable:
l
↓
┌───────────────┐ ┌───────────────┐ ┌───────────────┐
│ sibling: ─────────► │ sibling: NULL │ │ sibling: ─┐ │
│ │ │ │ ◄───────────────┘ │
└───────────────┘ └───────────────┘ └───────────────┘
↑
head
Now we get to the statement: l->sibling->sibling = l
. That means an assignment is made to the sibling
member of the middle node, and so we get:
l
↓
┌───────────────┐ ┌───────────────┐ ┌───────────────┐
│ sibling: ─────────► │ sibling: ─┐ │ │ sibling: ─┐ │
│ │ ◄───────────────┘ │ ◄───────────────┘ │
└───────────────┘ └───────────────┘ └───────────────┘
↑
head
We execute l->sibling = NULL
:
l
↓
┌───────────────┐ ┌───────────────┐ ┌───────────────┐
│ sibling: NULL │ │ sibling: ─┐ │ │ sibling: ─┐ │
│ │ ◄───────────────┘ │ ◄───────────────┘ │
└───────────────┘ └───────────────┘ └───────────────┘
↑
head
And finally, we return head
. The local variables end their lifetimes, and so only the returned pointer is relevant:
┌───────────────┐ ┌───────────────┐ ┌───────────────┐
│ sibling: NULL │ │ sibling: ─┐ │ │ sibling: ─┐ │
│ │ ◄───────────────┘ │ ◄───────────────┘ │
└───────────────┘ └───────────────┘ └───────────────┘
↑
(returned)
You can see that the returned pointer is indeed referencing the reversed list.