Problem:
Binary Search Tree II

Write a program which performs the following operations to a binary search tree $T$ by adding the find operation to A: Binary Search Tree I.

insert $k$: Insert a node containing $k$ as key into $T$.

find $k$: Report whether $T$ has a node containing $k$.

print: Print the keys of the binary search tree by inorder tree walk and preorder tree walk respectively.

Input

In the first line, the number of operations $m$ is given. In the following $m$ lines, operations represented by insert $k$, find $k$ or print are given.

Output

For each find $k$ operation, print "yes" if $T$ has a node containing $k$, "no" if not.

In addition, for each print operation, print a list of keys obtained by inorder tree walk and preorder tree walk in a line respectively. Put a space character before each key.

Constraints

The number of operations $\leq 500,000$

The number of print operations $\leq 10$.

$-2,000,000,000 \leq key \leq 2,000,000,000$

The height of the binary tree does not exceed 100 if you employ the above pseudo code.

The keys in the binary search tree are all different.

Sample Input 1

10
insert 30
insert 88
insert 12
insert 1
insert 20
find 12
insert 17
insert 25
find 16
print

Sample Output 1

yes
no
1 12 17 20 25 30 88
30 12 1 20 17 25 88

Reference

Introduction to Algorithms, Thomas H. Cormen, Charles E. Leiserson, Ronald L. Rivest, and Clifford Stein. The MIT Press.

Solution in Go (judge verdict: Accepted)

package main

import (
	"bufio"
	"os"
	"fmt"
	"strconv"
)

type Node struct {
	value int
	left *Node
	right *Node
}


/****************************************************************
*関数insert():													*
*	 挿入される二分探索木のrootノードを表すポインタrootと				*
*	 挿入したいノードのvalueを引数に、適切な葉に新たなノードを挿入して、	*
*	 挿入された二分探索木のルートノードのポインタを返す関数				*
*****************************************************************/
func insert(root *Node, val int) *Node {

	// 二分探索木がまだ構築されていないときはここが呼び出される
	if root == nil {
		return &Node{val, nil,nil}
	}

	// すでにある二分探索木に対するノード（value: val）を挿入する
	// ここを抜けるとparentに挿入されるノードの親へのポインタが入っている
	// 変数nodeは、挿入すべき場所を探すための一時的なポインタ変数
	var parent *Node
	node := root
	for node != nil {
		parent = node
		if node.value > val {
			node = node.left
		} else {
			node = node.right
		}
	}

	// 新たなノードの挿入を実行
	if parent.value > val {
		parent.left = &Node{val, nil,nil}
	} else {
		parent.right = &Node{val, nil, nil}
	}

	// 二分探索木の根は変わらないのでそのまま返す
	return root
}

func printNodes(nodes []int) {
	// 木の走査によって得られたint型スライスを引数に、
	// 指定されたフォーマットに出力する関数
	writer := bufio.NewWriter(os.Stdout)
	for _, v := range nodes{
		writer.Write([]byte(fmt.Sprintf(" %d", v)))
	}
	writer.Write([]byte("\n"))
	writer.Flush()
}

func preorder(root *Node, memo []int) []int {
	// 引数rootが根となっている二分探索木に対して先行巡回によって
	// 各ノードをを舐めて、引数memoで与えられる空のスライスに書き込み、
	// 書き込まれた後のスライスを返す関数
	if root != nil {
		memo = append(memo, root.value)
		memo = preorder(root.left, memo)
		memo = preorder(root.right, memo)
	}
	return memo
}

func inorder(root *Node, memo []int) []int {
	// 引数rootが根となっている二分探索木に対して中間巡回によって
	// 各ノードをを舐めて、引数memoで与えられる空のスライスに書き込み、
	// 書き込まれた後のスライスを返す関数
	if root != nil {
		memo = inorder(root.left, memo)
		memo = append(memo, root.value)
		memo = inorder(root.right, memo)
	}
	return memo
}

/****************************************************************
*関数find():														*
*	 探索対象の二分探索木のrootノードを表すポインタrootと				*
*	 探したいノードのtargetを引数に、								*
*	 存在すればtrueを、なければfalseを返す関数						*
*****************************************************************/
func find(root *Node, target int) bool {
	switch {
	//　rootを根とする二分探索木が未構築
	case root == nil:
		return false
	case root.value == target:
		return true
	case root.value > target:
		return find(root.left, target)
	default:
		return find(root.right, target)
	}
}

func main() {
	var n int
	var root *Node
	scanner := bufio.NewScanner(os.Stdin)
	scanner.Split(bufio.ScanWords)
	scanner.Scan()
	n, _  = strconv.Atoi(scanner.Text())
	for i := 0; i < n; i++ {
		scanner.Scan()
		operation := scanner.Text()
		switch operation {
		case "insert":
			scanner.Scan()
			value, _ := strconv.Atoi(scanner.Text())
			root = insert(root, value)
		case "print":
			printNodes(inorder(root, []int{}))
			printNodes(preorder(root, []int{}))
		case "find":
			scanner.Scan()
			target, _ := strconv.Atoi(scanner.Text())
			if find(root, target) {
				fmt.Println("yes")
			} else {
				fmt.Println("no")
			}
		default:
			panic("No such operation!")
		}
	}
}