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

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using CompProgLib.Tree;
using CompProgLib.Tree.BinaryTree;

namespace ALDS1_8_B
{
    public class Program

    {
        public static void Main(string[] args)
        {
            int n = ReadInt();
            BinaryTree<int> bt = new BinaryTree<int>();
            for (int i = 0 ; i < n ; i++)
            {
                string[] line = ReadStAr();
                switch (line[0])
                {
                    case "insert":
                        bt.Add(int.Parse(line[1]));
                        break;
                    case "find":
                        Console.WriteLine(bt.Contains(int.Parse(line[1])) ? "yes" : "no");
                        break;
                    case "print":
                        Console.WriteLine(" " + string.Join(" ", bt.InorderTraversal(bt.Root).Select(x => x.ToString()).ToArray()));
                        Console.WriteLine(" " + string.Join(" ", bt.PreorderTraversal(bt.Root).Select(x => x.ToString()).ToArray()));
                        break;
                    default:
                        break;
                }
            }

        }

        static string ReadSt() { return Console.ReadLine(); }
        static int ReadInt() { return int.Parse(Console.ReadLine()); }
        static long ReadLong() { return long.Parse(Console.ReadLine()); }
        static double ReadDouble() { return double.Parse(Console.ReadLine()); }
        static string[] ReadStAr(char sep = ' ') { return Console.ReadLine().Split(sep); }
        static int[] ReadIntAr(char sep = ' ') { return Array.ConvertAll(Console.ReadLine().Split(sep), e => int.Parse(e)); }
        static long[] ReadLongAr(char sep = ' ') { return Array.ConvertAll(Console.ReadLine().Split(sep), e => long.Parse(e)); }
        static double[] ReadDoubleAr(char sep = ' ') { return Array.ConvertAll(Console.ReadLine().Split(sep), e => double.Parse(e)); }

    }
    
}

namespace CompProgLib.Tree
{
    public class Node<T>
    {
        public T Value { get; set; }
        public Node<T> Parent { get; set; }
        protected NodeList<T> Neighbors { get; set; }

        public Node() { }
        public Node(T data) : this(data, null) { }
        public Node(T data, NodeList<T> neighbors)
        {
            Value = data;
            Neighbors = neighbors;
        }
    }

    public class NodeList<T> : List<Node<T>>
    {
        public NodeList() : base() { }
        public NodeList(int initialSize)
        { for (int i = 0 ; i < initialSize ; i++) Add(default(Node<T>)); }

        public Node<T> FindByValue(T value)
        {
            foreach (Node<T> node in this) if (node.Value.Equals(value)) return node;
            return null;
        }
    }
}


namespace CompProgLib.Tree.BinaryTree
{
    public class BinaryTreeNode<T> : Node<T>
    {
        public BinaryTreeNode() : base() { }
        public BinaryTreeNode(T data) : base(data, null) { }
        public BinaryTreeNode(T data, BinaryTreeNode<T> left, BinaryTreeNode<T> right)
        {
            Value = data;
            Neighbors = new NodeList<T> { left, right };
        }

        public BinaryTreeNode<T> Left
        {
            get
            {
                if (base.Neighbors == null) return null;
                else return (BinaryTreeNode<T>)Neighbors[0];
            }
            set
            {
                if (base.Neighbors == null) base.Neighbors = new NodeList<T>(2);
                base.Neighbors[0] = value;
                if ( value != null) value.Parent = Neighbors[0];
            }
        }

        public BinaryTreeNode<T> Right
        {
            get
            {
                if (base.Neighbors == null) return null;
                else return (BinaryTreeNode<T>)base.Neighbors[1];
            }
            set
            {
                if (base.Neighbors == null) base.Neighbors = new NodeList<T>(2);
                base.Neighbors[1] = value;
                if (value != null)  value.Parent = Neighbors[1];
            }
        }
    }

    public class BinaryTreeNodeList<T> :NodeList<T>
    {
        public BinaryTreeNodeList() : base() { }
        public BinaryTreeNodeList(int initialSize)
        { for (int i = 0 ; i < initialSize ; i++) Add(default(BinaryTreeNode<T>)); }

        public new BinaryTreeNode<T> FindByValue(T value)
        {
            foreach (BinaryTreeNode<T> node in this) if (node.Value.Equals(value)) return node;
            return null;
        }
    }

    public class BinaryTree<T>
    {

        public BinaryTreeNode<T> Root { get; set; }

        public BinaryTree() { Root = null; }
        public virtual void Clear() { Root = null; }

        public List<T> PreorderTraversal(BinaryTreeNode<T> current)
        {
            List<T> res = new List<T>();
            PreorderTraversal(current, res);
            return res;
        }
        private void PreorderTraversal(BinaryTreeNode<T> current,List<T> res)
        {
            if (current != null)
            {
                res.Add(current.Value);
                PreorderTraversal(current.Left, res);
                PreorderTraversal(current.Right,res);
            }
        }

        public List<T> InorderTraversal(BinaryTreeNode<T> current)
        {
            List<T> res = new List<T>();
            InorderTraversal(current, res);
            return res;
        }
        private void InorderTraversal(BinaryTreeNode<T> current, List<T> res)
        {
            if (current != null)
            {
                InorderTraversal(current.Left, res);
                res.Add(current.Value);
                InorderTraversal(current.Right, res);
            }
        }

        public List<T> PostorderTraversal(BinaryTreeNode<T> current)
        {
            List<T> res = new List<T>();
            PostorderTraversal(current, res);
            return res;
        }
        private void PostorderTraversal(BinaryTreeNode<T> current, List<T> res)
        {
            if (current != null)
            {
                PostorderTraversal(current.Left, res);
                PostorderTraversal(current.Right, res);
                res.Add(current.Value);
            }
        }

        public virtual void Add(T data)
        {
          
            BinaryTreeNode<T> n = new BinaryTreeNode<T>(data);
            int result;
            System.Collections.Comparer comparer = new System.Collections.Comparer(System.Globalization.CultureInfo.CurrentCulture);

            BinaryTreeNode<T> current = Root, parent = null;
            while (current != null)
            {
                result = comparer.Compare(current.Value, data);
                if (result == 0)
                     return;
                else if (result > 0)
                {
                    parent = current;
                    current = current.Left;
                }
                else if (result < 0)
                {               
                    parent = current;
                    current = current.Right;
                }
            }

            if (parent == null)
                Root = n;
            else
            {
                result = comparer.Compare(parent.Value, data);
                if (result > 0)
                    parent.Left = n;
                else
                    parent.Right = n;
            }
        }

        public bool Contains(T data)
        {
            BinaryTreeNode<T> current = Root;
            int result;

            System.Collections.Comparer comparer = new System.Collections.Comparer(System.Globalization.CultureInfo.CurrentCulture);
            while (current != null)
            {
                result = comparer.Compare(current.Value, data);
                if (result == 0)
                    return true;
                else if (result > 0)
                    current = current.Left;
                else if (result < 0)
                    current = current.Right;
            }

            return false;      
        }

    }

}