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:
#!/usr/bin/env python3
# -*- coding: utf-8 -*-

"""
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

output: found + in_order + pre_order
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

"""

import sys


class Node(object):
    __slots__ = ('data', 'left', 'right')

    def __init__(self, data):
        self.data = data
        self.left, self.right = None, None

    def insert(self, data):
        """
        Insert data according to BST rules
        """
        if data < self.data:
            if not self.left:
                self.left = Node(data)
            else:
                self.left.insert(data)
        # insert duplicate value to right
        else:
            if not self.right:
                self.right = Node(data)
            else:
                self.right.insert(data)

        return self.data

    def find(self, data, parent=None):
        """
        Find node with given data, tree walk as insert goes
        """
        if data < self.data:
            if not self.left:
                return None, None
            return self.left.find(data=data, parent=self)
        elif data > self.data:
            if not self.right:
                return None, None
            return self.right.find(data=data, parent=self)
        else:
            return self, parent

    def children_count(self):
        """
        For choosing node deleting strategy
        """
        cnt = 0
        if self.left:
            cnt += 1
        if self.right:
            cnt += 1
        return cnt

    def delete(self, data):
        """
        delete node with given data
        """
        node, parent = self.find(data)
        if node:
            children_count = node.children_count()
            if not children_count:
                # delete reference to parent
                if parent.left is node:
                    parent.left = None
                else:
                    parent.right = None
                del node
            elif children_count == 1:
                # node's son becomes parents' son
                if node.left:
                    n = node.left
                else:
                    n = node.right
                if parent:
                    if parent.left is node:
                        parent.left = n
                    else:
                        parent.right = n
                del node
            else:
                # current node has two real children(as a partial root)
                # while the real successor couldn't have two real children
                successor = node.right
                while successor.left:
                    successor = successor.left
                copy_data = successor.data
                self.delete(copy_data)
                node.data = copy_data


def in_order_yield(node):
    if node.left:
        yield from in_order_yield(node.left)
    yield node.data
    if node.right:
        yield from in_order_yield(node.right)


def pre_order_yield(node):
    yield node.data

    for child in [node.left, node.right]:
        if child:
            yield from pre_order_yield(child)


def in_order_legacy(node):
    if node.left:
        yield node.left
    yield node.data
    if node.right:
        yield node.right


def pre_order_legacy(node):
    yield node.data
    for child in node.left, node.right:
        if child:
            yield child


def traversal(node, traversal_method):
    stack = [traversal_method(node)]
    while stack:
        last = stack[-1]
        try:
            _new = next(last)
        except StopIteration:
            stack.pop()
        else:
            if isinstance(_new, Node):
                stack.append(traversal_method(_new))
            elif isinstance(_new, int):
                yield _new


def action(_command, _content):
    # start all action from tree_root -- insert, find, delete, print
    if _command.startswith('in'):
        tree_root.insert(int(_content))

    elif _command.startswith('fi'):
        if tree_root.find(int(_content)) == (None, None):
            print('no')
        else:
            print('yes')

    elif _command.startswith('de'):
        tree_root.delete(int(_content))

    # print tree walk
    else:
        print('', *traversal(tree_root, traversal_method=in_order_legacy))
        print('', *traversal(tree_root, traversal_method=pre_order_legacy))
        # print('', *in_order_yield(tree_root))
        # print('', *pre_order_yield(tree_root))

    return None


if __name__ == '__main__':
    _input = sys.stdin.readlines()
    array_length = int(_input[0])
    command_list = list(map(lambda x: x.split(), _input[1:]))
    # assert len(command_list) == array_length

    flag, tree_root = False, None
    allowed_commands = ('insert', 'print', 'delete', 'find')

    for each in command_list:
        command, content = each[0], each[-1]
        if command not in allowed_commands:
            raise SystemExit('Illegal command!')

        # init the whole tree
        if not flag:
            if not command.startswith('in'):
                raise SystemExit('Please insert tree root first.')
            flag, tree_root = True, Node(data=int(content))
            continue
        action(command, content)

Submission status: Accepted

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

"""
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

output: found + in_order + pre_order
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

"""

import sys


class Node(object):
    __slots__ = ('data', 'left', 'right')

    def __init__(self, data):
        self.data = data
        self.left, self.right = None, None

    def insert(self, data):
        """
        Insert data according to BST rules
        """
        if data < self.data:
            if not self.left:
                self.left = Node(data)
            else:
                self.left.insert(data)
        # insert duplicate value to right
        else:
            if not self.right:
                self.right = Node(data)
            else:
                self.right.insert(data)

        return self.data

    def find(self, data, parent=None):
        """
        Find node with given data, tree walk as insert goes
        """
        if data < self.data:
            if not self.left:
                return None, None
            return self.left.find(data=data, parent=self)
        elif data > self.data:
            if not self.right:
                return None, None
            return self.right.find(data=data, parent=self)
        else:
            return self, parent

    def children_count(self):
        """
        For choosing node deleting strategy
        """
        cnt = 0
        if self.left:
            cnt += 1
        if self.right:
            cnt += 1
        return cnt

    def delete(self, data):
        """
        delete node with given data
        """
        node, parent = self.find(data)
        if node:
            children_count = node.children_count()
            if not children_count:
                # delete reference to parent
                if parent.left is node:
                    parent.left = None
                else:
                    parent.right = None
                del node
            elif children_count == 1:
                # node's son becomes parents' son
                if node.left:
                    n = node.left
                else:
                    n = node.right
                if parent:
                    if parent.left is node:
                        parent.left = n
                    else:
                        parent.right = n
                del node
            else:
                # current node has two real children(as a partial root)
                # while the real successor couldn't have two real children
                successor = node.right
                while successor.left:
                    successor = successor.left
                copy_data = successor.data
                self.delete(copy_data)
                node.data = copy_data


def in_order_yield(node):
    if node.left:
        yield from in_order_yield(node.left)
    yield node.data
    if node.right:
        yield from in_order_yield(node.right)


def pre_order_yield(node):
    yield node.data

    for child in [node.left, node.right]:
        if child:
            yield from pre_order_yield(child)


def in_order_legacy(node):
    if node.left:
        yield node.left
    yield node.data
    if node.right:
        yield node.right


def pre_order_legacy(node):
    yield node.data
    for child in node.left, node.right:
        if child:
            yield child


def traversal(node, traversal_method):
    stack = [traversal_method(node)]
    while stack:
        last = stack[-1]
        try:
            _new = next(last)
        except StopIteration:
            stack.pop()
        else:
            if isinstance(_new, Node):
                stack.append(traversal_method(_new))
            elif isinstance(_new, int):
                yield _new


def action(_command, _content):
    # start all action from tree_root -- insert, find, delete, print
    if _command.startswith('in'):
        tree_root.insert(int(_content))

    elif _command.startswith('fi'):
        if tree_root.find(int(_content)) == (None, None):
            print('no')
        else:
            print('yes')

    elif _command.startswith('de'):
        tree_root.delete(int(_content))

    # print tree walk
    else:
        # print('', *traversal(tree_root, traversal_method=in_order_legacy))
        # print('', *traversal(tree_root, traversal_method=pre_order_legacy))
        print('', *in_order_yield(tree_root))
        print('', *pre_order_yield(tree_root))

    return None


if __name__ == '__main__':
    _input = sys.stdin.readlines()
    array_length = int(_input[0])
    command_list = list(map(lambda x: x.split(), _input[1:]))
    # assert len(command_list) == array_length

    flag, tree_root = False, None
    allowed_commands = ('insert', 'print', 'delete', 'find')

    for each in command_list:
        command, content = each[0], each[-1]
        if command not in allowed_commands:
            raise SystemExit('Illegal command!')

        # init the whole tree
        if not flag:
            if not command.startswith('in'):
                raise SystemExit('Please insert tree root first.')
            flag, tree_root = True, Node(data=int(content))
            continue
        action(command, content)

Submission status: Accepted

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

"""
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

output: found + in_order + pre_order
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

"""

import sys


class Node(object):
    __slots__ = ('data', 'left', 'right')

    def __init__(self, data):
        self.data = data
        self.left, self.right = None, None

    def insert(self, data):
        """
        Insert data according to BST rules
        """
        if data < self.data:
            if not self.left:
                self.left = Node(data)
            else:
                self.left.insert(data)
        # insert duplicate value to right
        else:
            if not self.right:
                self.right = Node(data)
            else:
                self.right.insert(data)

        return self.data

    def find(self, data, parent=None):
        """
        Find node with given data, tree walk as insert goes
        """
        if data < self.data:
            if not self.left:
                return None, None
            return self.left.find(data=data, parent=self)
        elif data > self.data:
            if not self.right:
                return None, None
            return self.right.find(data=data, parent=self)
        else:
            return self, parent

    def children_count(self):
        """
        For choosing node deleting strategy
        """
        cnt = 0
        if self.left:
            cnt += 1
        if self.right:
            cnt += 1
        return cnt

    def delete(self, data):
        """
        delete node with given data
        """
        node, parent = self.find(data)
        if node:
            children_count = node.children_count()
            if not children_count:
                # delete reference to parent
                if parent.left is node:
                    parent.left = None
                else:
                    parent.right = None
                del node
            elif children_count == 1:
                # node's son becomes parents' son
                if node.left:
                    n = node.left
                else:
                    n = node.right
                if parent:
                    if parent.left is node:
                        parent.left = n
                    else:
                        parent.right = n
                del node
            else:
                # current node has two real children(as a partial root)
                # while the real successor couldn't have two real children
                successor = node.right
                while successor.left:
                    successor = successor.left
                copy_data = successor.data
                self.delete(copy_data)
                node.data = copy_data


def in_order_yield(node):
    if node.left:
        yield from in_order_yield(node.left)
    yield node.data
    if node.right:
        yield from in_order_yield(node.right)


def pre_order_yield(node):
    yield node.data

    for child in node.left, node.right:
        if child:
            yield from pre_order_yield(child)


def in_order_legacy(node):
    if node.left:
        yield node.left
    yield node.data
    if node.right:
        yield node.right


def pre_order_legacy(node):
    yield node.data
    for child in node.left, node.right:
        if child:
            yield child


def traversal(node, traversal_method):
    stack = [traversal_method(node)]
    while stack:
        last = stack[-1]
        try:
            node_new = next(last)
        except StopIteration:
            stack.pop()
        else:
            if isinstance(node_new, Node):
                stack.append(traversal_method(node_new))
            elif isinstance(node_new, int):
                yield node_new


def action(_command, _content):
    # start all action from tree_root -- insert, find, delete, print
    if _command.startswith('in'):
        tree_root.insert(int(_content))

    elif _command.startswith('fi'):
        if tree_root.find(int(_content)) == (None, None):
            print('no')
        else:
            print('yes')

    elif _command.startswith('de'):
        tree_root.delete(int(_content))

    # print tree walk
    else:
        # print('', *traversal(tree_root, traversal_method=in_order_legacy))
        # print('', *traversal(tree_root, traversal_method=pre_order_legacy))
        print('', *in_order_yield(tree_root))
        print('', *pre_order_yield(tree_root))

    return None


if __name__ == '__main__':
    _input = sys.stdin.readlines()
    array_length = int(_input[0])
    command_list = list(map(lambda x: x.split(), _input[1:]))
    # assert len(command_list) == array_length

    flag, tree_root = False, None
    allowed_commands = ('insert', 'print', 'delete', 'find')

    for each in command_list:
        command, content = each[0], each[-1]
        if command not in allowed_commands:
            raise SystemExit('Illegal command!')

        # init the whole tree
        if not flag:
            if not command.startswith('in'):
                raise SystemExit('Please insert tree root first.')
            flag, tree_root = True, Node(data=int(content))
            continue
        action(command, content)

Submission status: Accepted

Solution code:
#http://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=ALDS1_8_A
#???????????? 15??? 8A????????????

def insert(root, insert_node):
    focus_node = root
    parent = None
    while not focus_node == None:
        parent = focus_node
        if focus_node["data"]  > insert_node["data"]:
            focus_node = focus_node["left"]
        else:
            focus_node = focus_node["right"]

    if parent["data"] > insert_node["data"]:
        parent["left"] = insert_node
        insert_node["parent"] = parent
    else:
        parent["right"] = insert_node
        insert_node["parent"] = parent

def get_preorder(node):
    if node == None:
        return []
    r = []
    r.append(str(node["data"]))
    r.extend(get_preorder(node["left"]))
    r.extend(get_preorder(node["right"]))

    return r
    
def get_inorder(node):
    if node == None:
        return []
    r = []
    r.extend(get_inorder(node["left"]))
    r.append(str(node["data"]))
    r.extend(get_inorder(node["right"]))

    return r

def delete_tree(root, target):
    
    delete_node = find_tree(root, target)
    parent = delete_node["parent"]
    if parent["left"] == delete_node:
        parent_direction = "left"
    else:
        parent_direction = "right"
    
    while True:
        if delete_node["left"] == None and delete_node["right"] == None:
            parent[parent_direction] = None
            break
        elif delete_node["left"] and delete_node["right"]:
            p = get_inorder(root)
            next_num = int(p[p.index(str(delete_node["data"])) + 1])
            tmp_delete_node = find_tree(root, next_num)
            delete_node["data"] = next_num
            delete_node = tmp_delete_node
            parent = delete_node["parent"]
            if parent == None:
                parent_direction = None
            elif parent["left"] == delete_node:
                parent_direction = "left"
            else:
                parent_direction = "right"
        else:
            if delete_node["left"]:
                parent[parent_direction] = delete_node["left"]
                delete_node["left"]["parent"] = parent
            else:
                parent[parent_direction] = delete_node["right"]
                delete_node["right"]["parent"] = parent
            break

    
def find_tree(root, target):
    focus_node = root

    while not focus_node == None:
        if focus_node["data"] == target:
            return focus_node
        elif focus_node["data"] < target:
            focus_node = focus_node["right"]
        else:
            focus_node = focus_node["left"]
    
    return None
    
def print_tree(root):
    print(" " + " ".join(get_inorder(root)))
    print(" " + " ".join(get_preorder(root)))
    
def main():
    
    n_line = int(input())
    input_list = [input() for i in range(n_line)]
    root = {"left":None, "right": None, "data":int(input_list[0].split()[1]), "parent": None}

    for line in input_list[1:]:
        if line == "print":
            print_tree(root)
        else:
            split_line = line.split()
            if split_line[0] == "insert":
                node = {"left":None, "right": None, "data":int(split_line[1]), "parent":None}
                insert(root, node)
            elif split_line[0] == "find":
                if find_tree(root, int(split_line[1])):
                    print("yes")
                else:
                    print("no")
            elif split_line[0] == "delete":
                delete_tree(root, int(split_line[1]))
        
        

if __name__ == "__main__":
    main()

Submission status: Accepted

Solution code:
#http://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=ALDS1_8_A
#???????????? 15??? 8A????????????

def insert(root, insert_node):
    focus_node = root
    parent = None
    while not focus_node == None:
        parent = focus_node
        if focus_node["data"]  > insert_node["data"]:
            focus_node = focus_node["left"]
        else:
            focus_node = focus_node["right"]

    if parent["data"] > insert_node["data"]:
        parent["left"] = insert_node
        insert_node["parent"] = parent
    else:
        parent["right"] = insert_node
        insert_node["parent"] = parent

def get_preorder(node):
    if node == None:
        return []
    r = []
    r.append(str(node["data"]))
    r.extend(get_preorder(node["left"]))
    r.extend(get_preorder(node["right"]))

    return r
    
def get_inorder(node):
    if node == None:
        return []
    r = []
    r.extend(get_inorder(node["left"]))
    r.append(str(node["data"]))
    r.extend(get_inorder(node["right"]))

    return r

def delete_tree(root, target):
    
    delete_node = find_tree(root, target)
    parent = delete_node["parent"]
    if parent["left"] == delete_node:
        parent_direction = "left"
    else:
        parent_direction = "right"
    
    while True:
        if delete_node["left"] == None and delete_node["right"] == None:
            parent[parent_direction] = None
            break
        elif delete_node["left"] and delete_node["right"]:
            p = get_inorder(root)
            next_num = int(p[p.index(str(delete_node["data"])) + 1])
            tmp_delete_node = find_tree(root, next_num)
            delete_node["data"] = next_num
            delete_node = tmp_delete_node
            parent = delete_node["parent"]
            if parent == None:
                parent_direction = None
            elif parent["left"] == delete_node:
                parent_direction = "left"
            else:
                parent_direction = "right"
        else:
            if delete_node["left"]:
                parent[parent_direction] = delete_node["left"]
                delete_node["left"]["parent"] = parent
            else:
                parent[parent_direction] = delete_node["right"]
                delete_node["right"]["parent"] = parent
            break

    
def find_tree(root, target):
    focus_node = root

    while not focus_node == None:
        if focus_node["data"] == target:
            return focus_node
        elif focus_node["data"] < target:
            focus_node = focus_node["right"]
        else:
            focus_node = focus_node["left"]
    
    return None
    
def print_tree(root):
    print(" " + " ".join(get_inorder(root)))
    print(" " + " ".join(get_preorder(root)))
    
def main():
    
    n_line = int(input())
    input_list = [input() for i in range(n_line)]
    root = {"left":None, "right": None, "data":int(input_list[0].split()[1]), "parent": None}

    for line in input_list[1:]:
        if line == "print":
            print_tree(root)
        else:
            split_line = line.split()
            target = int(split_line[1])
            if split_line[0] == "insert":
                node = {"left":None, "right": None, "data":int(split_line[1]), "parent":None}
                insert(root, node)
            elif split_line[0] == "find":
                if find_tree(root, target):
                    print("yes")
                else:
                    print("no")
            elif split_line[0] == "delete":
                delete_tree(root, target)
        
        

if __name__ == "__main__":
    main()

Submission status: Accepted

Solution code:
class Node(object):
    root = None

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

    @classmethod
    def insert(cls, z):
        y = None
        x = cls.root
        while x != None:  # root???????????????????????????y????????\????????????????????¨???????????§??¨????????????
            y = x
            if z.key < x.key:
                x = x.left
            else:
                x = x.right
        # ?????\?????¨?????????????????????????¨??????????
        z.parent = y
        if y == None:
            cls.root = z
        elif z.key < y.key:
            y.left = z
        else:
            y.right = z
        # return z

    @classmethod
    def find(cls, k):
        """ ??????k?????????????????¢?????????????????????????????°None????????? """
        x = cls.root
        while x != None and k != x.key:
            if k < x.key:
                x = x.left
            else:
                x = x.right
        return x

    @classmethod
    def walk_preorder(cls, node):
        """ ??????????????? """
        # results = []
        # results.append(node.key)
        print(' {0}'.format(node.key), end='')
        if node.left != None:
            # results.append(cls.walk_preorder(node.left))
            cls.walk_preorder(node.left)
        if node.right != None:
            # results.append(cls.walk_preorder(node.right))
            cls.walk_preorder(node.right)
        #return results

    @classmethod
    def walk_inorder(cls, node):
        """ ??????????????? """
        # results = []
        if node.left != None:
            # results.append(cls.walk_inorder(node.left))
            cls.walk_inorder(node.left)
        # results.append(node.key)
        print(' {0}'.format(node.key), end='')
        if node.right != None:
            # results.append(cls.walk_inorder(node.right))
            cls.walk_inorder(node.right)
        # return results

    @classmethod
    def delete_node(cls, z):
        if z.left == None or z.right == None:
            y = z
        else:
            y = Node.get_successor(z)
        if y.left != None:
            x = y.left
        else:
            x = y.right
        if x != None:
            x.parent = y.parent
        if y.parent == None:
            Node.root = x
        elif y == y.parent.left:
            y.parent.left = x
        else:
            y.parent.right = x
        if y != z:
            z.key = y.key

    @classmethod
    def get_successor(cls, x):
        if x.right != None:
            return Node.get_minimum(x.right)
        y = x.parent
        while y != None and x == y.right:
            x = yy = y.parent
        return y

    @classmethod
    def get_minimum(cls, x):
        """ ??????x????????¨????????¨?????¨????????§????°?????????????????????????????????? """
        while x.left != None:
            x = x.left
        return x

    def get_type(self):
        if self.parent == None:
            return 'root'
        elif self.left == None and self.right == None:
            return 'leaf'
        else:
            return 'internal node'

    def get_depth(self):
        if self.parent == None:
            return 0
        else:
            depth = 1
            t = self.parent
            while t.parent != None:
                t = t.parent
                depth += 1
            return depth

    def get_height(self):
        if self.height:
            return self.height
        h_left = 0
        h_right = 0
        if self.left != None:
            h_left = self.left.get_height() + 1
        if self.right != None:
            h_right = self.right.get_height() + 1
        self.height = max(h_left, h_right)
        return self.height

    def get_degree(self):
        degree = 0
        if self.left != None:
            degree += 1
        if self.right != None:
            degree += 1
        return degree

    def get_sibling(self):
        if self.parent == None:
            return -1
        p = self.parent
        if p.left != self and p.left != None:
            return p.left
        if p.right != self and p.right != None:
            return p.right


def process_node_data(node_data):
    for inst in node_data:
        if inst[0] == 'print':
            result = Node.walk_inorder(Node.root)
            print('')
            # print(' {0}'.format(' '.join(map(str, flatten(result)))))
            result = Node.walk_preorder(Node.root)
            # print(' {0}'.format(' '.join(map(str, flatten(result)))))
            print('')
        elif inst[0] == 'insert':
            node_key = int(inst[1])
            new_node = Node(node_key)
            Node.insert(new_node)
        elif inst[0] == 'find':
            result = Node.find(int(inst[1]))
            if result:
                print('yes')
            else:
                print('no')
        elif inst[0] == 'delete':
            result = Node.delete_node(Node.find(int(inst[1])))



def flatten(l):
    """ http://stackoverflow.com/questions/2158395/flatten-an-irregular-list-of-lists-in-python """
    import collections
    for el in l:
        if isinstance(el, collections.Iterable) and not isinstance(el, (str, bytes)):
            yield from flatten(el)
        else:
            yield el


if __name__ == '__main__':
    # ??????????????\???
    num_of_nodes = int(input())
    node_data = [input().split(' ') for _ in range(num_of_nodes)]
    # node_data = []
    # with open('ALDS1_8_A-in4.txt') as f:
    #     for line in f:
    #        if ' ' not in line:
    #           num_of_nodes = (int(line))
    #       else:
    #           node_data.append(line.split(' '))

    # ???????????????
    # ??¨???????????????
    process_node_data(node_data)