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 Scala (judge verdict: Accepted)

import scala.io.StdIn.{readInt, readLine}
object Main {
    def main(args: Array[String]): Unit = {
        val cnt = readInt;
        val binTree = new BinaryTree[Long,Boolean]((k1, k2) => if (k1 < k2) -1 else if (k1 > k2) 1 else 0);
        (0 until cnt).foreach { i =>
            readLine.split(" ") match {
                case Array("insert", key) => binTree.insert(key.toLong, true);
                case Array("find", key) => {
                    if (binTree.find(key.toLong)) println("yes") else println("no");
                }
                case Array("print") => {
                    println(" " + binTree.fetchInorder.map(_._1).mkString(" "));
                    println(" " + binTree.fetchPreoder.map(_._1).mkString(" "));
                }
            }
        }
    }
}
class BinaryTree[A,B](val compare: (A,A) => Int) {
    case class TreeNode(key: A, value: B, var left: TreeNode, var right: TreeNode);
    var tree: TreeNode = null;
    
    def isEmpty(): Boolean = if (tree == null) true else false;
    
    def insert(key: A, value: B): Unit = {
        def _insert(curr: TreeNode): Unit = {
            if (compare(key, curr.key) < 0) { // 追加対象ノードのほうが小さい
                if (curr.left == null) curr.left = TreeNode(key, value, null, null) else _insert(curr.left);
            } else if (compare(key, curr.key) > 0) { // 追加対象ノードのほうが大きい
                if (curr.right == null) curr.right = TreeNode(key, value, null, null) else _insert(curr.right);
            }
        }
        if (isEmpty) tree = TreeNode(key, value, null, null) else _insert(tree);
    }
    
    def find(key: A): Boolean = {
        def _find(curr: TreeNode): Boolean = {
            if (compare(key, curr.key) == 0) {
                true;
            } else if (compare(key, curr.key) < 0) {
                if (curr.left == null) false else _find(curr.left);
            } else {
                if (curr.right == null) false else _find(curr.right);
            }
        }
        if (isEmpty) false else _find(tree);
    }

    // 先行巡回で要素を返す
    def fetchPreoder(): List[(A, B)] = {
        def _fetchPreoder(curr: TreeNode, ret: List[(A, B)]): List[(A, B)] = {
            if (curr == null) {
                ret;
            } else {
                val ret1 = (curr.key, curr.value) :: ret;
                val ret2 = _fetchPreoder(curr.left, ret1);
                val ret3 = _fetchPreoder(curr.right, ret2);
                ret3;
            }
        }
        _fetchPreoder(tree, Nil).reverse;
    }
    
    // 中間巡回で要素を返す
    def fetchInorder(): List[(A, B)] = {
        def _fetchInorder(curr: TreeNode, ret: List[(A, B)]): List[(A, B)] = {
            if (curr == null) {
                ret;
            } else {
                val ret1 = _fetchInorder(curr.left, ret);
                val ret2 = (curr.key, curr.value) :: ret1;
                val ret3 = _fetchInorder(curr.right, ret2);
                ret3;
            }
        }
        _fetchInorder(tree, Nil).reverse;
    }
}