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.Diagnostics;
using System.Linq;
using System.Security.Cryptography.X509Certificates;
using System.Text;

/*
 */

public class ALDS1_8_B
{
    private struct Node
    {
        public int NodeId;
        public int Value;
        public int ParentId;
        public int LeftId;
        public int RightId;

        public Node(int nodeId)
        {
            NodeId = nodeId;
            Value = 0;
            ParentId = -2;
            LeftId = -1;
            RightId = -1;
        }
    }

    public static void Main(string[] args)
    {
        //var exStdIn = new System.IO.StreamReader( "input.txt" );
        //System.Console.SetIn( exStdIn );

        int n = int.Parse(Console.ReadLine());
        Node[] nodes = new Node[n];
        for (int i = 0; i < n; i++)
        {
            nodes[i] = new Node(i);
        }

        int index = 0;
        for (int i = 0; i < n; i++)
        {
            string[] str = Console.ReadLine().Split(' ');
            if (str[0] == "insert")
            {
                Insert(nodes, index, int.Parse(str[1]));
                index++;
            }
            else if (str[0] == "find")
            {
                int rootId = GetRootId(nodes);
                Find(nodes, rootId, int.Parse(str[1]));
            }
            else if (str[0] == "print")
            {
                int rootId = GetRootId(nodes);
                StringBuilder sb = new StringBuilder();
                Inorder(nodes, sb, rootId);
                sb.AppendLine();
                Preorder(nodes, sb, rootId);
                Console.WriteLine(sb.ToString());
            }
        }
    }

    private static int GetRootId(Node[] nodes)
    {
        int rootId = -1;
        for (int j = 0; j < nodes.Length; j++)
        {
            if (nodes[j].ParentId == -1)
            {
                rootId = j;
                break;
            }
        }
        return rootId;
    }

    private static void Insert(Node[] nodes, int index, int value)
    {
        nodes[index].Value = value;
        int parent = GetRootId(nodes);
        if (parent == -1)
        {
            nodes[index].ParentId = -1;
            return;
        }
        while (true)
        {
            Node parentNode = nodes[parent];
            if (value < parentNode.Value)
            {
                if (parentNode.LeftId != -1)
                {
                    parent = parentNode.LeftId;
                }
                else
                {
                    nodes[parent].LeftId = index;
                    nodes[index].ParentId = parent;
                    return;
                }
            }
            else
            {
                if (parentNode.RightId != -1)
                {
                    parent = parentNode.RightId;
                }
                else
                {
                    nodes[parent].RightId = index;
                    nodes[index].ParentId = parent;
                    return;
                }
            }
        }
    }

    private static void Find(Node[] nodes, int index, int value)
    {
        if (index == -1)
        {
            Console.WriteLine("no");
            return;
        }
        if (nodes[index].Value == value)
        {
            Console.WriteLine("yes");
            return;
        }

        if (value < nodes[index].Value)
        {
            Find(nodes, nodes[index].LeftId, value);
        }
        else
        {
            Find(nodes, nodes[index].RightId, value);
        }
    }

    private static void Preorder(Node[] nodes, StringBuilder sb, int index)
    {
        sb.AppendFormat(" {0}", nodes[index].Value.ToString());
        if (nodes[index].LeftId != -1)
        {
            Preorder(nodes, sb, nodes[index].LeftId);
        }
        if (nodes[index].RightId != -1)
        {
            Preorder(nodes, sb, nodes[index].RightId);
        }
    }

    private static void Inorder(Node[] nodes, StringBuilder sb, int index)
    {
        if (nodes[index].LeftId != -1)
        {
            Inorder(nodes, sb, nodes[index].LeftId);
        }
        sb.AppendFormat(" {0}", nodes[index].Value.ToString());
        if (nodes[index].RightId != -1)
        {
            Inorder(nodes, sb, nodes[index].RightId);
        }
    }

    private static void Postorder(Node[] nodes, StringBuilder sb, int index)
    {
        if (nodes[index].LeftId != -1)
        {
            Postorder(nodes, sb, nodes[index].LeftId);
        }
        if (nodes[index].RightId != -1)
        {
            Postorder(nodes, sb, nodes[index].RightId);
        }
        sb.AppendFormat(" {0}", nodes[index].Value.ToString());
    }
}