package main
import "fmt"
type TreeNode struct {
Val int
Left *TreeNode
Right *TreeNode
}
func morrisInorder(root *TreeNode) {
curr := root
for curr != nil {
if curr.Left == nil {
fmt.Printf("%d -> ", curr.Val) // print current node
curr = curr.Right // move right
} else {
// find inorder predecessor
pre := curr.Left
for pre.Right != nil && pre.Right != curr {
pre = pre.Right // move to rightmost node in left subtree
}
if pre.Right == nil {
pre.Right = curr // create thread
curr = curr.Left // move left
} else {
pre.Right = nil // remove thread
fmt.Printf("%d -> ", curr.Val) // print current node
curr = curr.Right // move right
}
}
}
fmt.Print("null\n")
}
func main() {
// Construct tree:
// 4
// / \
// 2 5
// / \
// 1 3
root := &TreeNode{4, nil, nil}
root.Left = &TreeNode{2, nil, nil}
root.Right = &TreeNode{5, nil, nil}
root.Left.Left = &TreeNode{1, nil, nil}
root.Left.Right = &TreeNode{3, nil, nil}
morrisInorder(root)
}
loop until all nodes are visited
if no left child, visit node and move right
fmt.Printf("%d -> ", curr.Val)
print current node value
find inorder predecessor in left subtree
for pre.Right != nil && pre.Right != curr { pre = pre.Right }
move to rightmost node of left subtree or thread back to curr
if pre.Right == nil { pre.Right = curr; curr = curr.Left }
create thread and move left
else { pre.Right = nil; print curr; curr = curr.Right }
remove thread, visit node, move right
1 -> 2 -> 3 -> 4 -> 5 -> null