Problem:

Binary Search Tree III

Write a program which performs the following operations to a binary search tree $T$ by adding delete operation to B: Binary Search Tree II.

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

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

  
delete $k$: Delete a node containing $k$.

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

The operation delete $k$ for deleting a given node $z$ containing key $k$ from $T$ can be implemented by an algorithm which considers the following cases:

 If $z$ has no children, we modify its parent $z.p$ to replace $z$ with NIL as its child (delete $z$).

 If $z$ has only a single child, we "splice out" $z$ by making a new link between its child and its parent.

 If $z$ has two children, we splice out $z$'s successor $y$ and replace $z$'s key with $y$'s key.

Input

   In the first line, the number of operations $m$ is given. In the following $m$ lines, operations represented by insert $k$, find $k$, delete $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

18
insert 8
insert 2
insert 3
insert 7
insert 22
insert 1
find 1
find 2
find 3
find 4
find 5
find 6
find 7
find 8
print
delete 3
delete 7
print

Sample Output 1

yes
yes
yes
no
no
no
yes
yes
 1 2 3 7 8 22
 8 2 1 3 7 22
 1 2 8 22
 8 2 1 22

Reference

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



Sample input:
18
insert 8
insert 2
insert 3
insert 7
insert 22
insert 1
find 1
find 2
find 3
find 4
find 5
find 6
find 7
find 8
print
delete 3
delete 7
print


Sample output:
yes
yes
yes
no
no
no
yes
yes
 1 2 3 7 8 22
 8 2 1 3 7 22
 1 2 8 22
 8 2 1 22

Submission status: Accepted

Solution code:
import sys

class Node:
    parent = None
    left = None
    right = None

    def __init__(self, key):
        self.key = key

    def __repr__(self):
        return "({},{},{},{})".format(self.key, self.parent, self.left, self.right)

    def is_root(self):
        return self.parent is None

    def is_leaf(self):
        return self.left is None and self.right is None

    def has_one_child(self):
        if self.is_leaf():
            return False
        elif (self.left is None) and (self.right is not None):
            return self.right
        elif (self.left is not None) and (self.right is None):
            return self.left
        else:
            return False

    def has_two_child(self):
        return (self.left is not None) and (self.right is not None)


root_node_no = None

def insert(nodes :dict, in_node :Node):
    global root_node_no

    cur_node_no = root_node_no
    parent_node_no = None
    while cur_node_no is not None:
        parent_node_no = cur_node_no
        if in_node.key < cur_node_no:
            cur_node_no = nodes[cur_node_no].left
        else:
            cur_node_no = nodes[cur_node_no].right

    in_node.parent = parent_node_no

    if root_node_no is None:
        root_node_no = in_node.key
    elif in_node.key < parent_node_no:
        nodes[parent_node_no].left = in_node.key
    else:
        nodes[parent_node_no].right = in_node.key

    nodes[in_node.key] = in_node

def inorder_tree_walk(nodes, node_no ,inorder):
    if node_no is None:
        return
    inorder_tree_walk(nodes, nodes[node_no].left, inorder)
    inorder.append(node_no)
    inorder_tree_walk(nodes, nodes[node_no].right, inorder)

def preorder_tree_walk(nodes, node_no, preorder):
    if node_no is None:
        return
    preorder.append(node_no)
    preorder_tree_walk(nodes, nodes[node_no].left, preorder)
    preorder_tree_walk(nodes, nodes[node_no].right, preorder)


def find(nodes, tgt_node_no):
    cur_node_no = root_node_no
    while cur_node_no is not None:
        cur_node = nodes[cur_node_no]
        if cur_node.key == tgt_node_no:
            return True
        elif tgt_node_no < cur_node.key:
            cur_node_no = cur_node.left
        else:
            cur_node_no = cur_node.right
    return False


def switch_child_of_parent(nodes: dict, del_node: Node, switch_node_no):
    if nodes[del_node.parent].left == del_node.key:
        nodes[del_node.parent].left = switch_node_no
    elif nodes[del_node.parent].right == del_node.key:
        nodes[del_node.parent].right = switch_node_no
    return


def delete_node(nodes: dict, delete_node_no: int):
    del_node = nodes[delete_node_no]

    if del_node.is_leaf():
        # delete leaf
        switch_child_of_parent(nodes, del_node, None)
    elif not del_node.has_two_child():
        # delete one child node
        child = del_node.has_one_child()
        switch_child_of_parent(nodes, del_node, child)
        nodes[child].parent = del_node.parent
    else:
        # delete two child node
        inorder = []
        inorder_tree_walk(nodes, del_node.right, inorder)
        swap_node = Node(inorder[0])
        switch_child_of_parent(nodes, del_node, swap_node.key)

        swap_node.parent = del_node.parent
        swap_node.left = del_node.left
        if swap_node.key == del_node.right:
            swap_node.right = None
        else:
            swap_node.right = del_node.right
            nodes[swap_node.right].parent = swap_node.key
        nodes[swap_node.left].parent = swap_node.key
        delete_node(nodes, swap_node.key)
        nodes[swap_node.key] = swap_node

    del nodes[delete_node_no]
    return


def main():
    num_com = int(input())
    commands = sys.stdin.readlines()
    nodes = {}
    for i in range(num_com):
        if commands[i][0] == 'i':
            insert(nodes, Node(int(commands[i][7:])))
        elif commands[i][0] == 'p':
            # inorder
            inorder = []
            inorder_tree_walk(nodes, root_node_no, inorder)
            print(" " + " ".join(map(str, inorder)))
            # preorder
            preorder = []
            preorder_tree_walk(nodes, root_node_no, preorder)
            print(" " + " ".join(map(str, preorder)))
        elif commands[i][0] == 'f':
            if find(nodes, int(commands[i][5:])):
                print('yes')
            else:
                print('no')
        elif commands[i][0] == 'd':
            delete_node(nodes, int(commands[i][7:]))

main()

Submission status: Accepted

Solution code:
class Node:
    def __init__(self,key):
        self.key=key
        self.parent=None
        self.left=None
        self.right=None


def insert(root,node):#rootを根に持つ２分探索木にnodeを追加する
    if(root.key <= node.key):
        if(root.right is None):
            root.right=node
            node.parent=root
        else:
            insert(root.right,node)
    
    else:
        if(root.left is None):
            root.left=node
            node.parent=root
        else:
            insert(root.left,node)


def find(root,key):
    if(root.key==key):
        return root

    elif(root.key < key):
        if(root.right is not None):
            return find(root.right,key)
        else:
            return None

    else:
        if(root.left is not None):
            return find(root.left,key)
        else:
            return None






def delete(Root,key):
    root=Root[0]
    target=find(root,key)#targetは削除対象のnode
    if(target is None):
        pass

    elif(target.parent is None):
        return 0



    else:
        parent=target.parent

        if(parent.key <= target.key):
            right=1
        else:
            right=0
        #targetがparentの右の子の時はright=1、左の子の時はright=0

        if((target.left is None) and (target.right is None)):
            if(right):
                parent.right=None
            else:
                parent.left=None

        elif(target.left is None):
            target.right.parent=parent
            if(right):
                parent.right=target.right
            else:
                parent.left=target.right

        elif(target.right is None):
            target.left.parent=parent
            if(right):
                parent.right=target.left
            else:
                parent.left=target.left
        
        else:
            tmp_min=target.right
            while(tmp_min.left is not None):#targetの右の子を根とする部分木の中で最小のnodeを見つける
                tmp_min=tmp_min.left
            
            if(tmp_min.parent.key <=tmp_min.key):#最小値が、targetの右の子だった場合
                if(right):
                    parent.right=tmp_min
                else:
                    parent.left=tmp_min
                tmp_min.parent=parent
                tmp_min.left=target.left
                target.left.parent=tmp_min
                return 1
            
            if(tmp_min.right is not None):#tmpが右の子を持っていた時の処理
                tmp_min.parent.left=tmp_min.right
                tmp_min.right.parent=tmp_min.parent
            
            tmp_min.parent.left=None
            tmp_min.left=target.left
            target.left.parent=tmp_min
            tmp_min.right=target.right
            target.right.parent=tmp_min
            tmp_min.parent=parent
            if(right):
                parent.right=tmp_min
            else:
                parent.left=tmp_min
    return 1

                   
            
        



    

def Preorder(root,order):
    order.append(root.key)
    if(root.left is not None):
        Preorder(root.left,order)
    
    if(root.right is not None):
        Preorder(root.right,order)




def Inorder(root,order):
    if(root.left is not None):
        Inorder(root.left,order)
    
    order.append(root.key)


    if(root.right is not None):
        Inorder(root.right,order)




n=int(input())



root=None


for loop in range(n):
    ope=input().split()

    if(ope[0]=="insert"):
        tmp_node=Node(int(ope[1]))
        try:
            insert(root,tmp_node)
        except:
            root=tmp_node
    
    elif(ope[0]=="find"):
        try:
            if(find(root,int(ope[1])) is not None):
                print("yes")

            else:
                print("no")
        except:
            print("no")
    
    elif(ope[0]=="delete"):
        Root=[root]
        if(delete(Root,int(ope[1])) ==0):
            root=None

    else:
        in_order=[]
        p_order=[]

        
        Inorder(root,in_order)
        Preorder(root,p_order)

        for x in in_order:
            print(f" {x}",end="")
            
        print()
        for x in p_order:
            print(f" {x}",end="")
        print()

Submission status: Accepted

Solution code:
from collections import deque
import sys
readline = sys.stdin.readline
write = sys.stdout.write

root = None
def insert(z):
    global root
    y = None
    x = root
    while x:
        y = x
        x = x[z[2] >= x[2]]
    z[3] = y

    if not y:
        root = z
    else:
        y.__setitem__(z[2] >= y[2], z)

def find(k):
    x = root
    while x:
        if x[2] == k:
            return 1
        x = x[k >= x[2]]
    return 0

def __delete(x):
    global root
    if x[0] and x[1]:
        y = x[1]
        while y[0]:
            y = y[0]
        x[2] = y[2]
        __delete(y)
    elif not x[0] and not x[1]:
        if x[3]:
            p = x[3]
            p.__setitem__(p[1] is x, None)
        else:
            root = None
        del x
    else:
        y = x[0] or x[1]

        if x[3]:
            p = x[3]

            y[3] = p
            p[p[1] is x] = y
        else:
            y[3] = None
            root = y
        del x

def delete(k):
    x = root
    while x:
        if x[2] == k:
            break
        x = x[k >= x[2]]
    if not x:
        return
    __delete(x)

def debug():
    s0 = [""]
    s1 = [""]

    def dfs(nd):
        v = str(nd[2])
        s0.append(v)
        if nd[0]:
            dfs(nd[0])
        s1.append(v)
        if nd[1]:
            dfs(nd[1])
    dfs(root)
    return " ".join(s1), " ".join(s0)


M = int(readline())
ans = []
for m in range(M):
    cmd, *V, = readline().split()
    if cmd == "print":
        ans.extend(debug())
    elif cmd == "find":
        ans.append("yes" if find(int(V[0])) else "no")
    elif cmd == "delete":
        delete(int(V[0]))
    else:
        insert([None, None, int(V[0]), None])
write("\n".join(ans))
write("\n")

Submission status: Accepted

Solution code:
class Node:
    def __init__(self, key, parent=None, left=None, right=None):
        self.key = key
        self.parent = parent
        self.left = left
        self.right = right
         
 
def get_minimum(node):
    x = node
    while x.left is not None:
        x = x.left
    return x
 
class Tree:
    def __init__(self):
        self.root_node = None
         
    def insert(self, z):
        y = None # y stands for the parent of x
        x = self.root_node # root node
        # First, we ascend the tree until the point where we insert the new node
        while x is not None:
            y = x # set parent
            if z.key < x.key:
                x = x.left # move to the left child
            else:
                x = x.right # move to the right child
        # insert z under y
        z.parent = y
         
        if y is None:
            # when the tree is empty
            self.root_node = z
        elif z.key < y.key:
            y.left = z
        else:
            y.right = z
     
    def find(self, k):
        x = self.root_node
        while (x is not None) and (x.key != k):
            x = x.left if (k < x.key) else x.right            
        return x
 
    def delete_node(self, z):
        # determine y, the node to be deleted
        y = z if ((z.left is None) or (z.right is None)) else get_minimum(z.right)
        # determine x, the child of y (note that y has at most one child)
        x = y.left if (y.left is not None) else y.right
        # set the parent of x (if x is not None)
        if x is not None:
            x.parent = y.parent
         
        if y.parent is None:
            self.root_node = x
        elif y is y.parent.left:
            y.parent.left = x
        else:
            y.parent.right = x
         
        if y is not z:
            z.key = y.key
    
 
    def print_preorder(self, node):
        print(f" {node.key}", end="")
        if node.left is not None:
            self.print_preorder(node.left)
        if node.right is not None:
            self.print_preorder(node.right)
 
    def print_inorder(self, node):
        if node.left is not None:
            self.print_inorder(node.left)
        print(f" {node.key}", end="")
        if node.right is not None:
            self.print_inorder(node.right)
 
    def print_nodes(self):
        if self.root_node is None:
            pass
        else:
            self.print_inorder(self.root_node)
            print("")
            self.print_preorder(self.root_node)
            print("")
         

tree = Tree()

m = int(input())
for _ in range(m):
    command = input().split()
    if command[0] == 'print':
        tree.print_nodes()
    elif command[0] == 'find':
        node = tree.find(int(command[1]))
        print("no") if (node is None) else print("yes")
    elif command[0] == 'delete':
        x = tree.find(int(command[1]))
        tree.delete_node(x)
    else:
        key = int(command[1])
        new_node = Node(key)
        tree.insert(new_node)

Submission status: Accepted

Solution code:
#! /usr/bin/env python3
# -*- coding: utf-8 -*-

from sys import stdin
from random import randrange


class Tree():
    def __init__(self):
        self.root = None

    def insert(self, z):

        y = None
        x = self.root

        while x is not None:
            y = x
            if z.key < x.key:
                x = x.left
            else:
                x = x.right

        z.parent = y
        if y is None:
            self.root = z
        elif z.key < y.key:
            y.left = z
        else:
            y.right = z

    def find(self, key):
        x = self.root
        while x is not None:
            if key == x.key:
                return x
            elif key < x.key:
                x = x.left
            else:
                x = x.right
        return None

    def delete_node(self, x):
        if x.left is None and x.right is None:
            if x.parent is None:
                self.root = None
            elif x.parent.left == x:
                x.parent.left = None
            else:
                x.parent.right = None
        elif x.left is None:
            if x.parent is None:
                self.root = x.right
            elif x.parent.left == x:
                x.parent.left = x.right
            else:
                x.parent.right = x.right
            x.right.parent = x.parent
        elif x.right is None:
            if x.parent is None:
                self.root = x.left
            elif x.parent.left == x:
                x.parent.left = x.left
            else:
                x.parent.right = x.left
            x.left.parent = x.parent

    def delete(self, key):
        x = self.find(key)
        if x.left is None or x.right is None:
            self.delete_node(x)
        elif x.right.left is None:
            x.key = x.right.key
            self.delete_node(x.right)
        else:
            y = x.right.leftmost_child()
            x.key = y.key
            self.delete_node(y)

    def fold_inorder(self, f, init):
        def rec(node, b):
            nonlocal f, init

            if not node:
                return b
            else:
                return rec(node.right,
                           f(node.key,
                             rec(node.left, b)))

        return rec(self.root, init)

    def flatten_inorder(self):
        return self.fold_inorder(
            lambda a, b: b + [a],
            [])

    def foreach_inorder(self, f):

        def rec(node):
            if not node:
                return
            else:
                rec(node.left)
                f(node.key)
                rec(node.right)

        rec(self.root)

    def print_inorder(self):
        self.foreach_inorder(
            lambda a: print("", a, end="")
        )
        print()

    def print_preorder(self):

        def rec(node):
            if not node:
                return
            else:
                print("", node.key, end="")
                rec(node.left)
                rec(node.right)

        rec(self.root)
        print()

    def __str__(self):
        return str(self.root) if self.root else "()"


class Node():
    def __init__(self, key, parent=None, left=None, right=None):
        self.key = key
        self.parent = parent
        self.left = left
        self.right = right

    def rightmost_child(self):
        x = self
        while x.right is not None:
            x = x.right
        return x

    def leftmost_child(self):
        x = self
        while x.left is not None:
            x = x.left
        return x

    def __str__(self):
        return "({} {} {})".format(
            self.key, self.left, self.right)


def process(commands):
    T = Tree()
    for cmd in commands:
        if cmd[0] == "insert":
            T.insert(Node(int(cmd[1])))
        elif cmd[0] == "find":
            print("yes" if T.find(int(cmd[1])) else "no")
        elif cmd[0] == "delete":
            T.delete(int(cmd[1]))
        elif cmd[0] == "print":
            T.print_inorder()
            T.print_preorder()
    return T


def main():
    _ = int(stdin.readline())
    commands = []
    for line in stdin:
        commands.append(line.split())
    process(commands)


def test_a_case(name, commands, expected):
    result = str(process(commands))
    assert result == expected, name + " " + result


def test():
    test_a_case(
        "test1",
        [
        ],
        "()")
    test_a_case(
        "test2",
        [
            ["insert", "1"],
        ],
        "(1 None None)")
    test_a_case(
        "test3",
        [
            ["insert", "1"],
            ["delete", "1"],
        ],
        "()")


def random_test_repr(n, p, q, T):
    return "n:{}\np:{}\nq:{}\nT:{}".format(
        n, p, q, str(T))


def test_a_random_case(p, q):
    T = Tree()
    inserted = []

    for n in p:
        assert not T.find(n), \
            "Before Insert:\n" + \
            random_test_repr(n, p, q, str(T))
        T.insert(Node(n))
        assert T.find(n), \
            "After Insert:\n" + \
            random_test_repr(n, p, q, str(T))

        inserted.append(n)
        assert T.flatten_inorder() == sorted(inserted), \
            "Inorder(Inserting):\n" + \
            random_test_repr(n, p, q, str(T))

    for n in q:
        T.delete(n)
        assert not T.find(n), \
            "After Delete:\n" + \
            random_test_repr(n, p, q, str(T))

        inserted.remove(n)
        assert T.flatten_inorder() == sorted(inserted), \
            "Inorder(Deleting):\n" + \
            random_test_repr(n, p, q, str(T))


def random_array(l):
    arr = list(range(l))
    for i in range(l):
        j = randrange(l)
        tmp = arr[i]
        arr[i] = arr[j]
        arr[j] = tmp
    return arr


def random_test():
    N = 10000
    L = 7

    for i in range(N):
        test_a_random_case(
            random_array(L), random_array(L))


"""
test()
random_test()
exit()
"""

main()

Submission status: Accepted

Solution code:
import sys
class Node:
    __slots__ = ['key', 'left', 'right']
    def __init__(self, key):
        self.key = key
        self.left = self.right = None

root = None
def delete(target):
    def remove_node(p, c, a):
        if p.left == c:
            p.left = a
        else:
            p.right = a
    p, c = None, root
    while c.key != target:
        p, c = c, c.left if target < c.key else c.right
    if c.left is None:
        remove_node(p, c, c.right)
    elif c.right is None:
        remove_node(p, c, c.left)
    elif c.right.left is None:
        c.right.left = c.left
        remove_node(p, c, c.right)
    else:
        g = c.right
        while g.left.left:
            g = g.left
        c.key = g.left.key
        g.left = g.left.right

def find(target):
    result = root
    while result and target != result.key:
        result = result.left if target < result.key else result.right
    if result is None:
        return False
    else:
        return True

def insert(key):
    global root
    y = None  # xの親
    x = root
    while x:
        y = x
        x = x.left if key < x.key else x.right
    if y is None:  # Tが空の場合
        root = Node(key)
    elif key < y.key:
        y.left = Node(key)
    else:
        y.right = Node(key)

def in_order(node):
    if node is None:
        return ''
    return in_order(node.left) + f' {node.key}' + in_order(node.right)
def pre_order(node):
    if node is None:
        return ''
    return f' {node.key}' + pre_order(node.left) + pre_order(node.right)
input()
for e in sys.stdin:
    if e[0] == 'i':
        insert(int(e[7:]))
    elif e[0] == 'd':
        delete(int(e[7:]))
    elif e[0] == 'f':
        print('yes' if find(int(e[5:])) else 'no')
    else:
        print(in_order(root))
        print(pre_order(root))

Submission status: Accepted

Solution code:
class Node():
    def __init__(self, key):
        self.key = key
        self.parent = None
        self.left = None
        self.right = None

class Tree():
    def __init__(self):
        self.root = None
        self.list = []

    def insert(self, node):
        y = None                 # x's parent    
        x = self.root
        while x is not None:
            y = x                # set parent
            if node.key < x.key:
                x = x.left
            else:
                x = x.right
        node.parent = y

        if y is None:
            self.root = node
        elif node.key < y.key:
            y.left = node
        else:
            y.right = node

    def find(self, key):
        node = self.root
        while node is not None and key != node.key:
            if key < node.key:
                node = node.left
            else:
                node = node.right
        return node

    def delete(self, node):
        target_node = None
        if node.left is None or node.right is None:
            target_node = node
        else:
            target_node = self.get_successor(node.right)

        target_child = None
        if target_node.left is not None:
            target_child = target_node.left
        else:
            target_child = target_node.right

        if target_child is not None:
            target_child.parent = target_node.parent

        if target_node.parent is None:
            self.root = target_child
        else:
            if target_node is target_node.parent.left:
                target_node.parent.left = target_child
            else:
                target_node.parent.right = target_child

        if target_node is not node:
            node.key = target_node.key

    def get_successor(self, node):
        if node.left is None:
            return node

        while node.left is not None:
            node = node.left
        return node

    def parse_inorder(self, node):
        if node is None:
            return 
        self.parse_inorder(node.left)
        self.list.append(node.key)
        self.parse_inorder(node.right)

    def parse_preorder(self, node):
        if node is None:
            return
        self.list.append(node.key)
        self.parse_preorder(node.left)
        self.parse_preorder(node.right)

N = int(input())
T = Tree()
for _ in range(N):
    order, *key = input().split()
    if order == "print":
        T.list = []
        T.parse_inorder(T.root)
        print(" " + " ".join(map(str, T.list)))
        T.list = []
        T.parse_preorder(T.root)
        print(" " + " ".join(map(str, T.list)))
    elif order == "find":
        # キーが見つかった時そのノードを返し、見つからなかった時はNoneを返す
        node = T.find(int(key[0]))
        if node is not None:
            print("yes")
        else:
            print("no")
    elif order == "delete":
        node = T.find(int(key[0]))
        if node is None:
            continue
        T.delete(node)
    else:
        node = Node(int(key[0]))
        T.insert(node)

Submission status: Accepted

Solution code:
class Node:
    def __init__(self, key):
        self.key = key
        self.parent = None
        self.left = None
        self.right = None
        
    def insert(self, z):
        if z.key < self.key:
            if self.left:
                self.left.insert(z)
            else:
                self.left = z
                z.parent = self
        else:
            if self.right:
                self.right.insert(z)
            else:
                self.right = z
                z.parent = self

    def find(self, key):
        if self.key == key:
            return True
        elif not self.left and not self.right:
            return False
        else:
            if key < self.key:
                return self.left.find(key)
            else:
                return self.right.find(key)
            
    def delete(self, key):
        if self.key == key:
            if not self.left and not self.right:
                if self.key < self.parent.key:
                    self.parent.left = None
                else:
                    self.parent.right = None
            elif self.left and self.right:
                A = [int(i) for i in self.ino().split()]
                ind = A.index(self.key)
                y = A[ind+1]
                self.delete(y)
                self.key = y
            else:
                if self.left:
                    self.left.parent = self.parent
                    if self.key < self.parent.key:
                        self.parent.left = self.left
                    else:
                        self.parent.right = self.left
                else:
                    self.right.parent = self.parent
                    if self.key < self.parent.key:
                        self.parent.left = self.right
                    else:
                        self.parent.right = self.right
        else:
            if self.key < key:
                self.right.delete(key)
            else:
                self.left.delete(key)
        
    def preo(self):
        tmp = ""
        tmp += " " + str(self.key)
        if self.left:
            tmp += self.left.preo()
        if self.right:
            tmp += self.right.preo()
        return tmp
    
    def ino(self):
        tmp = ""
        if self.left:
            tmp += self.left.ino()
        tmp += " " + str(self.key)
        if self.right:
            tmp += self.right.ino()
        return tmp
m = int(input())
root = None
for i in range(m):
    com = input().split()
    if com[0] == "insert":
        node = Node(int(com[1]))
        try:
            root.insert(node)
        except AttributeError :
            root = node
    elif com[0] == "find":
        try:
            if root.find(int(com[1])):
                print("yes")
            else:
                print("no")
        except AttributeError:
            print("no")
    elif com[0] == "delete":
        try:
            root.delete(int(com[1]))
        except AttributeError:
            print("failed deletion")
    else:
        try:
            print(root.ino())
            print(root.preo())
        except AttributeError:
            print("None")