package main
import "fmt"
type Node struct {
Val int
Left *Node
Right *Node
}
func isLeaf(node *Node) bool {
return node.Left == nil && node.Right == nil
}
func addLeftBoundary(node *Node, res *[]int) {
curr := node.Left
for curr != nil {
if !isLeaf(curr) {
*res = append(*res, curr.Val) // add left boundary node
}
if curr.Left != nil {
curr = curr.Left // go left if possible
} else {
curr = curr.Right // else go right
}
}
}
func addLeaves(node *Node, res *[]int) {
if node == nil {
return
}
if isLeaf(node) {
*res = append(*res, node.Val) // add leaf node
return
}
addLeaves(node.Left, res) // traverse left subtree
addLeaves(node.Right, res) // traverse right subtree
}
func addRightBoundary(node *Node, res *[]int) {
curr := node.Right
stack := []int{}
for curr != nil {
if !isLeaf(curr) {
stack = append(stack, curr.Val) // collect right boundary nodes
}
if curr.Right != nil {
curr = curr.Right // go right if possible
} else {
curr = curr.Left // else go left
}
}
// add right boundary nodes in reverse order
for i := len(stack) - 1; i >= 0; i-- {
*res = append(*res, stack[i])
}
}
func boundaryTraversal(root *Node) []int {
res := []int{}
if root == nil {
return res
}
res = append(res, root.Val) // add root
addLeftBoundary(root, &res) // add left boundary
addLeaves(root, &res) // add leaves
addRightBoundary(root, &res) // add right boundary
return res
}
func main() {
root := &Node{1, nil, nil}
root.Left = &Node{2, nil, nil}
root.Right = &Node{3, nil, nil}
root.Left.Left = &Node{4, nil, nil}
root.Left.Right = &Node{5, nil, nil}
root.Left.Right.Left = &Node{7, nil, nil}
root.Left.Right.Right = &Node{8, nil, nil}
root.Right.Right = &Node{6, nil, nil}
root.Right.Right.Left = &Node{9, nil, nil}
boundary := boundaryTraversal(root)
for i, v := range boundary {
if i == len(boundary)-1 {
fmt.Printf("%d -> null", v)
} else {
fmt.Printf("%d -> ", v)
}
}
fmt.Println()
}
res = append(res, root.Val) // add root
Add root node to result
curr := node.Left
for curr != nil {
if !isLeaf(curr) {
*res = append(*res, curr.Val) // add left boundary node
}
if curr.Left != nil {
curr = curr.Left // go left if possible
} else {
curr = curr.Right // else go right
}
}
Traverse left boundary top-down excluding leaves
if isLeaf(node) {
*res = append(*res, node.Val) // add leaf node
return
}
addLeaves(node.Left, res) // traverse left subtree
addLeaves(node.Right, res) // traverse right subtree
Add all leaf nodes from left to right
curr := node.Right
stack := []int{}
for curr != nil {
if !isLeaf(curr) {
stack = append(stack, curr.Val) // collect right boundary nodes
}
if curr.Right != nil {
curr = curr.Right // go right if possible
} else {
curr = curr.Left // else go left
}
}
for i := len(stack) - 1; i >= 0; i-- {
*res = append(*res, stack[i])
}
Traverse right boundary bottom-up excluding leaves using stack
1 -> 2 -> 4 -> 7 -> 8 -> 9 -> 6 -> 3 -> null