Step 1: Start at root 4, find predecessor in left subtree (rightmost of 2's subtree)
4 [curr] -> 2 -> 5 -> 1 -> 3
Predecessor of 4 is 3
Why: We need to find where to return after visiting left subtree
Step 2: Make 3's right point to 4 (thread), move curr to 2
4 -> 2 [curr] -> 5 -> 1 -> 3 -> 4 (thread)
Thread created to remember return
Why: Thread lets us come back to 4 after left subtree
Step 3: At 2, find predecessor (rightmost of 1's subtree), which is 1
4 -> 2 [curr] -> 5 -> 1 -> 3 -> 4 (thread)
Predecessor of 2 is 1
Why: Find return point after left subtree of 2
Step 4: Make 1's right point to 2 (thread), move curr to 1
4 -> 2 -> 5 -> 1 [curr] -> 3 -> 4 (thread)
1's right points to 2
Why: Thread remembers to return to 2 after 1
Step 5: At 1, no left child, print 1, move curr to right (which is thread to 2)
Printed: 1
4 -> 2 -> 5 -> 1 -> 3 -> 4
Curr moves to 2 via thread
Why: No left subtree, so print and return
Step 6: At 2, thread found from 1, remove thread, print 2, move curr to right 3
Printed: 1 -> 2
4 -> 2 -> 5 -> 1 -> 3 -> 4
Thread removed, curr at 3
Why: Left subtree done, print node and go right
Step 7: At 3, no left child, print 3, move curr to right (thread to 4)
Printed: 1 -> 2 -> 3
4 -> 2 -> 5 -> 1 -> 3 -> 4
Curr moves to 4 via thread
Why: No left subtree, print and return
Step 8: At 4, thread found from 3, remove thread, print 4, move curr to right 5
Printed: 1 -> 2 -> 3 -> 4
4 -> 2 -> 5 -> 1 -> 3 -> 4
Thread removed, curr at 5
Why: Left subtree done, print node and go right
Step 9: At 5, no left child, print 5, move curr to right null
Printed: 1 -> 2 -> 3 -> 4 -> 5
5 -> null
Traversal ends
Why: No left subtree, print and finish
Result: 1 -> 2 -> 3 -> 4 -> 5 -> null