The best way to understand a recursive function is to NOT follow the recursive calls. You are allowed to assume that the recursive calls do what they are supposed to do. Only consider the first level of the call.
The functions's purpose is to print directions to move 'disks' disks from peg 'from' to peg 'to', using peg 'temp' as an extra peg, and following the rule of never putting a larger disk on a smaller disk. The starting position is all disks in proper order on peg 1. It's interesting to note that the actual disks themselves are not represented in the program. The number of disks on the pegs at each moment is not kept track of, only the total number of disks.
Reading just the top level of the function (assuming the recursive calls do what they are supposed to do):
* print directions to move all but the biggest disk from peg 1 to peg 2.
* print the direction to move the biggest disk from peg 1 to peg 3.
* print directions to move the disks from peg 2 to peg 3.
That will obviously give the correct answer, so the function is correct. This kind of description does not usually satisfy the beginner, but this point of view is the soul of recursion.
There are a couple of other details to consider. You need to ensure that there is at least one base case and that the recursive calls move towards the base case(s). Each recursive call should work on a reduced problem.
To satisfy your curiosity, we can follow one or two of the recursive calls in the same manner (assuming their recursive calls do what they're supposed to). The first recursive call will be handled in the same way as the initial call. All but the biggest disk is moved from 'from' (for that call) to the 'temp' peg, then the biggest disk is moved to the 'to' peg, then the disks that were moved to the 'temp' peg are moved to the 'to' peg. The next level call is handled the same way, until the base case (0 disks) is reached.
You can trace out the stack frames, etc, but the simplifying nature of recursion is that you don't need to consider those details. There's a kind of magic to it.
You can see the recursive structure of the problem by looking at the first few solutions:
Move 0 disks:
do nothing
Move 1 disk:
1->3
Move 2 disks:
Move 1 disk:
1->2
1->3
Move 1 disk:
2->3
Move 3 disks:
Move 2 disks:
Move 1 disk:
1->3
1->2
Move 1 disk:
2->2
1->3
Move 2 disks:
Move 1 disk:
2->1
2->3
Move 1 disk:
1->3
Move 4 disks:
Move 3 disks:
Move 2 disks:
Move 1 disk:
1->2
1->3
Move 1 disk:
2->3
1->2
Move 2 disks:
Move 1 disk:
3->1
3->2
Move 1 disk:
1->2
1->3
Move 3 disks:
Move 2 disks:
Move 1 disk:
2->3
2->1
Move 1 disk:
3->1
2->3
Move 2 disks:
Move 1 disk:
1->2
1->3
Move 1 disk:
2->3 |