Reputation: 57
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?
Upvotes: 2
Views: 132
Reputation: 350300
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.
Upvotes: 2
Reputation: 1146
The code in the question is incorrect, this is the correct code
int RevertList(Node *h){
if (h->sibling != NULL){
RevertList(h->sibling);
(h->sibling)->sibling = h;
}
else
root = h;
}
RevertList
is a helper-function used when a node is deleted from a Binomial Heap.
When a node is deleted, it’s child and their siblings are detached from the Binomial Heap Structure. The RevertList
function reverses the order of the detached children, so they can be union-ed to the root list, in the correct order.
Take a look at this code for better understanding of how this works!
Below is an example, from the CLRS Textbook
Upvotes: 2