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:
class Node:
    def __init__(self, key, parent=None, left=None, right=None):
        self.key = key
        self.parent = parent
        self.left = left
        self.right = right


root = None

def insert(k):
    global root
    y = None
    x = root
    z = Node(k)

    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:
        root = z
    else:
        if z.key < y.key:
            y.left = z
        else:
            y.right = z


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


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


def treeSuccessor(x):
    if x.right is not None:
        return treeMinimum(x.right)
    y = x.parent
    while y is not None and x == y.right:
        x = y
        y = y.parent
    return y


def treeDelete(z):
    if z is None:
        return

    global root
    if z.left is None or z.right is None:
        y = z
    else:
        y = treeSuccessor(z)

    if y.left is not None:
        x = y.left
    else:
        x = y.right

    if x is not None:
        x.parent = y.parent

    if y.parent is None:
        root = x
    else:
        if y == y.parent.left:
            y.parent.left = x
        else:
            y.parent.right = x

    if y != z:
        z.key = y.key


def inorder(u):
    if u is None:
        return
    inorder(u.left)
    print(' %d' % u.key, end='')
    inorder(u.right)


def preorder(u):
    if u is None:
        return
    print(' %d' % u.key, end='')
    preorder(u.left)
    preorder(u.right)


n = int(input())
for i in range(n):
    cmd = input().split()
    if cmd[0] == 'insert':
        insert(int(cmd[1]))
    elif cmd[0] == 'find':
        if find(root, int(cmd[1])) is not None:
            print('yes')
        else:
            print('no')
    elif cmd[0] == 'delete':
        treeDelete(find(root, int(cmd[1])))
    elif cmd[0] == 'print':
        inorder(root)
        print()
        preorder(root)
        print()

Submission status: Accepted

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

class BST:
	def __init__(self):
		self.root = None
	
	def insert(self, key):
		parent = None
		current = self.root
		while current != None:
			parent = current
			if key < current.key:
				current = current.left
			else:
				current = current.right
		new = Node(key)
		new.parent = parent
		if parent == None:
			self.root = new
		elif key < parent.key:
			parent.left = new
		else:
			parent.right = new		
	
	def find(self, key):
		current = self.root
		while current != None:
			if key == current.key:
				return current
			if key < current.key:
				current = current.left
			else:
				current = current.right
		return None
		
	def delete(self, key):
		target = self.find(key)
		if target == None:
			return

		parent = target.parent
		if target.left == None or target.right == None:
			child = None
			if target.left != None:
				child = target.left
			elif target.right != None:
				child = target.right
			
			if child != None:
				child.parent = parent
	
			if parent == None:
				self.root = child
			elif parent.left == target:
				parent.left = child
			else:
				parent.right = child
		else:
			current = target.right
			while current.left != None:
				current = current.left
			target.key = current.key
			parent = current.parent
			if current.right != None:
				parent.left = current.right
				current.right.parent = parent
			else:
				if parent.left == current:
					parent.left = None
				else:
					parent.right = None
	
	def print(self):
		self.print_in_order(self.root)
		print()
		self.print_pre_order(self.root)
		print()
		
	def print_in_order(self, node):
		if node != None:
			self.print_in_order(node.left)
			print(' ' + str(node.key), end='')
			self.print_in_order(node.right)
		
	def print_pre_order(self, node):
		if node != None:
			print(' ' + str(node.key), end='')
			self.print_pre_order(node.left)
			self.print_pre_order(node.right)		

n = int(input())
bst = BST()
for i in range(n):
	cmd = list(map(str, input().split()))
	if cmd[0] == 'print':
		bst.print()
	else:
		key = int(cmd[1])
		if cmd[0] == 'insert':
			bst.insert(key)
		elif cmd[0] == 'find':
			if bst.find(key) != None:
				print('yes')
			else:
				print('no')
		else:
			bst.delete(key)

Submission status: Accepted

Solution code:
# Binary search trees - Binary Search Tree III
class Tree:
    def __init__(self):
        self.root = None
        self.size = 0
    
    def delete(self, key):
        nd = self.find(key)
        self._delete_node(nd)

    def _delete_node(self, nd):
        if not nd: raise # unexpected?
        dl = nd.num_child()
        parent = nd.parent
        if dl == 0:
            if parent.left == nd: parent.left = None
            elif parent.right == nd: parent.right = None
        elif dl == 1:
            l,r = nd.left,nd.right
            if l:
                l.parent = parent
                self._reconnect(parent, nd, l)
            elif r:
                r.parent = parent
                self._reconnect(parent, nd, r)
        else: # dl == 2
            nextnd = self._find_next_node(nd)
            nd.key = nextnd.key
            self._delete_node(nextnd)

    def _find_next_node(self, nd):
        """ Find a node that is next node to nd by "Inorder".
        """
        return self._find_next_left(nd.right)

    def _find_next_left(self, nd):
        """ Find most left node about a given node.
        """
        if nd.left: return self._find_next_left(nd.left)
        else: return nd

    def _reconnect(self, p, t, c):
        """ Change p's child into c from t.
            And change c's parent into p from t.
        """
        if p.left == t: p.left = c
        elif p.right == t: p.right = c

    def find(self, key):
        return self._find(key, self.root)

    def _find(self, key, nd):
        if not nd: return None
        if nd.key == key: return nd
        if key < nd.key:
            return self._find(key, nd.left)
        else:
            return self._find(key, nd.right)
    
    def printorder(self):
        self._preorder_walk(self.root)
        print()
        self._inorder_walk(self.root)
        print()

    def _inorder_walk(self, nd):
        print(' {0}'.format(nd.key), end='')
        if nd.left: self._inorder_walk(nd.left)
        if nd.right: self._inorder_walk(nd.right)

    def _preorder_walk(self, nd):
        if nd.left: self._preorder_walk(nd.left)
        print(' {0}'.format(nd.key), end='')
        if nd.right: self._preorder_walk(nd.right)

class Node:
    def num_child(self):
        d = 1 if self.left else 0
        d += 1 if self.right else 0
        return d
    def __init__(self, key):
        self.key = key
        self.right,self.left = None,None
        self.parent = None
    def __str__(self):
        return 'node key: ' + str(self.key)

def insert(T, z):
    y = None
    x = T.root
    while not x == None:
        y = x
        if z.key < x.key:
            x = x.left
        else:
            x = x.right
    z.parent = y
    if z.parent == None:
        T.root = z
    elif z.key < y.key:
        y.left = z
    else:
        y.right = z
    T.size += 1

m = int(input())
T = Tree()
for _ in range(m):
    ss = input().split()
    op = ss[0]
    if op == 'insert':
        v = int(ss[1])
        insert(T, Node(v))
    elif op == 'print':
        T.printorder()
    elif op == 'find':
        v = int(ss[1])
        if T.find(v): print('yes')
        else: print('no')
    elif op == 'delete':
        v = int(ss[1])
        T.delete(v)

Submission status: Runtime Error

Solution code:
# -*- coding: utf-8 -*-
"""
Created on Sat Mar  2 17:11:49 2019

@author: Yamazaki Kenichi
"""

m = int(input())
A = [list(input().split()) for i in range(m)]

T = [[-1,-1,-1,-1]]
def insert(T,u,x):
    if T[0][3] == -1:
        T[0][3] = x
        return
    if x < T[u][3]:
        if T[u][1] == -1:
            T[u][1] = len(T)
            T.append([u,-1,-1,x])
        else:
            insert(T,T[u][1],x)
    else:
        if T[u][2] == -1:
            T[u][2] = len(T)
            T.append([u,-1,-1,x])
        else:
            insert(T,T[u][2],x)
def ino(u):
    if T[u][1] != -1:
        ino(T[u][1])
    ino_res.append(str(T[u][3]))
    if T[u][2] != -1:
        ino(T[u][2])
def pre(u):
    pre_res.append(str(T[u][3]))
    if T[u][1] != -1:
        pre(T[u][1])
    if T[u][2] != -1:
        pre(T[u][2])
def find(u,x):
    if x == T[u][3]:
        return True
    elif x < T[u][3]:
        if T[u][1] == -1:
            return False
        return find(T[u][1],x)
    else:
        if T[u][2] == -1:
            return False
        return find(T[u][2],x)
def dele(u,x):
    if T[u][1] == -1 and T[u][2] == -1:
        if T[T[u][0]][1] == u:
            T[T[u][0]][1] = -1
        else:
            T[T[u][0]][2] = -1
    elif T[u][1] != -1 and T[u][2] != -1:
        T[u][3] = T[T[u][0]][3]
        if T[T[u][0]][1] == u:
            T[T[u][0]][1] = -1
        else:
            T[T[u][0]][2] = -1
        dele(T[u][0])
    elif T[u][1] != -1:
        if T[T[u][0]][1] == u:
            T[T[u][0]][1] = T[u][1]
            T[T[u][1]][0] = T[u][0]
        else:
            T[T[u][0]][2] = T[u][1]
            T[T[u][2]][0] = T[u][0]
    elif T[u][2] != -1:
        if T[T[u][0]][1] == u:
            T[T[u][0]][1] = T[u][2]
            T[T[u][1]][0] = T[u][0]
        else:
            T[T[u][0]][2] = T[u][2]
            T[T[u][2]][0] = T[u][0]
def delete(u,x):
    if x == T[u][3]:
        dele(u,x)
    elif x < T[u][3]:
        delete(T[u][1],x)
    else:
        delete(T[u][2],x)
for c in A:
    if c[0] == 'insert':
        insert(T,0,int(c[1]))
    elif c[0] == 'find':
        print('yes') if find(0,int(c[1])) else print('no')
    elif c[0] == 'delete':
        delete(0,int(c[1]))
    else:
        ino_res = []
        ino(0)
        pre_res = []
        pre(0)
        print(' '+' '.join(ino_res))
        print(' '+' '.join(pre_res))

Submission status: Runtime Error

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.inorder = []
        self.preorder = []

    def insert(self, node):

        p = None
        x = self.root        
        while x is not None:
            p = x
            # print(node.key, x.key)
            if node.key <= x.key:
                x = x.left
            else:
                x = x.right

        # insertするnodeの親を設定
        node.parent = p

        if p is None:
            self.root = node
        else:
            # insertするnodeを親のleftかrightに設定
            if node.key <= p.key:
                # print('leftに設定')
                p.left = node
            else:
                # print('rightに設定')
                p.right = node

    def find(self, key):
        # print('find: ', str(key))
        node = self.root
        while node is not None:
            if node.key == key:
                return node
            elif key <= node.key:
                node = node.left
            else:
                node = node.right
        return None

    def delete(self, z):
        # print("delete =========")
        # print(z.key)
        p = z.parent

        # 1. zが子を持たない場合
        if z.left is None and z.right is None:
            # print('pattern 1')
            if p.left.key == z.key:
                p.left = None
            else:
                p.right = None

        # 3. zが子を2つ持つ場合
        elif z.left is not None and z.right is not None:
            # print('pattern 2')
            next_node = tree.get_next_node(z)
            z.key = next_node.key
            if next_node == next_node.parent.left:
                next_node.parent.left = None
            else:
                next_node.parent.right = None

        # 2. zがちょうど1つの子を持つ場合
        else:
            # print('pattern 3')
            # zが左子だった場合
            if p.left.key == z.key:
                if z.left is not None:
                    p.left = z.left
                    z.left.parent = p
                else:
                    p.left = z.right
                    z.right.parent = p
            else:
                # zが右子だった場合
                if z.left is not None:
                    p.right = z.left
                    z.left.parent = p
                else:
                    p.right = z.right
                    z.right.parent = p

    def get_next_node(self, node):
        if node.right is not None:
            return self.get_minimum(node)
        p = x.parent
        while p is not None and p != p.parent.left:
            p = p.parent
        return p.parent

    def get_minimum(self, node):
        x = node
        while x.left is not None:
            x = x.left
        return x

    def print_inorder(self):
        self.inorder = []
        self.inorder_traverse(self.root)
        print(' ' + ' '.join(map(str, self.inorder)))

    def print_preorder(self):
        self.preorder = []
        self.preorder_traverse(self.root)
        print(' ' + ' '.join(map(str, self.preorder)))

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

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

tree = Tree()
m = int(input())
for i in range(m):
    line = input().split()
    if line[0] == 'print':
        tree.print_inorder()
        tree.print_preorder()
    elif line[0] == 'insert':
        key = int(line[1])
        tree.insert(Node(key))
    elif line[0] == 'find':
        key = int(line[1])
        if tree.find(key):
            print('yes')
        else:
            print('no')
    elif line[0] == 'delete':
        # print("current tree----")
        # print(tree.root.key)
        # print(tree.root.left.key)
        # print(tree.root.left.right.key)
        # print(tree.root.left.right.parent.key)
        # print("current tree----")
        key = int(line[1])
        node = tree.find(key)
        # print(node.key)
        tree.delete(node)

Submission status: Runtime Error

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.inorder = []
        self.preorder = []

    def insert(self, node):

        p = None
        x = self.root        
        while x is not None:
            p = x
            # print(node.key, x.key)
            if node.key <= x.key:
                x = x.left
            else:
                x = x.right

        # insertするnodeの親を設定
        node.parent = p

        if p is None:
            self.root = node
        else:
            # insertするnodeを親のleftかrightに設定
            if node.key <= p.key:
                # print('leftに設定')
                p.left = node
            else:
                # print('rightに設定')
                p.right = node

    def find(self, key):
        # print('find: ', str(key))
        node = self.root
        while node is not None:
            if node.key == key:
                return node
            elif key <= node.key:
                node = node.left
            else:
                node = node.right
        return None

    def delete(self, z):
        # print("delete =========", z.key)
        # print(z.key)
        # print(z.parent)
        p = z.parent

        # 1. zが子を持たない場合
        if z.left is None and z.right is None:
            # print('pattern 1')
            if p.left.key == z.key:
                p.left = None
            else:
                p.right = None

        # 3. zが子を2つ持つ場合
        elif z.left is not None and z.right is not None:
            # print('pattern 2')
            next_node = tree.get_next_node(z)
            z.key = next_node.key
            self.delete(next_node)

        # 2. zがちょうど1つの子を持つ場合
        else:
            # print('pattern 3')
            # zが左子だった場合
            if p.left.key == z.key:
                if z.left is not None:
                    p.left = z.left
                    z.left.parent = p
                else:
                    p.left = z.right
                    z.right.parent = p
            else:
                # zが右子だった場合
                if z.left is not None:
                    p.right = z.left
                    z.left.parent = p
                else:
                    p.right = z.right
                    z.right.parent = p

    def get_next_node(self, node):
        if node.right is not None:
            return self.get_minimum(node)
        p = x.parent
        while p is not None and p != p.parent.left:
            p = p.parent
        return p.parent

    def get_minimum(self, node):
        x = node
        while x.left is not None:
            x = x.left
        return x

    def print_inorder(self):
        self.inorder = []
        self.inorder_traverse(self.root)
        print(' ' + ' '.join(map(str, self.inorder)))

    def print_preorder(self):
        self.preorder = []
        self.preorder_traverse(self.root)
        print(' ' + ' '.join(map(str, self.preorder)))

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

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

tree = Tree()
m = int(input())
for i in range(m):
    line = input().split()
    if line[0] == 'print':
        tree.print_inorder()
        tree.print_preorder()
    elif line[0] == 'insert':
        key = int(line[1])
        tree.insert(Node(key))
    elif line[0] == 'find':
        key = int(line[1])
        if tree.find(key):
            print('yes')
        else:
            print('no')
    elif line[0] == 'delete':
        
        # print("current tree----")
        # print(tree.root.key)
        # print(tree.root.left.key)
        # print(tree.root.left.right.key)
        # print(tree.root.left.right.parent.key)
        # print("current tree----")
        key = int(line[1])
        # print('delete', str(key))
        node = tree.find(key)
        # print(node.key)
        tree.delete(node)

Submission status: Runtime Error

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.inorder = []
        self.preorder = []

    def insert(self, node):

        p = None
        x = self.root        
        while x is not None:
            p = x
            # print(node.key, x.key)
            if node.key <= x.key:
                x = x.left
            else:
                x = x.right

        # insertするnodeの親を設定
        node.parent = p

        if p is None:
            self.root = node
        else:
            # insertするnodeを親のleftかrightに設定
            if node.key <= p.key:
                # print('leftに設定')
                p.left = node
            else:
                # print('rightに設定')
                p.right = node

    def find(self, key):
        # print('find: ', str(key))
        node = self.root
        while node is not None:
            if node.key == key:
                return node
            elif key <= node.key:
                node = node.left
            else:
                node = node.right
        return None

    def delete(self, z):
        # print("delete =========", z.key)
        # print(z.key)
        # print(z.parent)
        p = z.parent
        # print(p.key)

        # 1. zが子を持たない場合
        if z.left is None and z.right is None:
            # print('pattern 1')
            if p.left == z:
                p.left = None
            else:
                p.right = None

        # 3. zが子を2つ持つ場合
        elif z.left is not None and z.right is not None:
            # print('pattern 2')
            next_node = tree.get_next_node(z)
            # print('next:', next_node.key)
            z.key = next_node.key
            self.delete(next_node)

        # 2. zがちょうど1つの子を持つ場合
        else:
            # print('pattern 3')
            # zが左子だった場合
            if p.left.key == z.key:
                if z.left is not None:
                    p.left = z.left
                    z.left.parent = p
                else:
                    p.left = z.right
                    z.right.parent = p
            else:
                # zが右子だった場合
                if z.left is not None:
                    p.right = z.left
                    z.left.parent = p
                else:
                    p.right = z.right
                    z.right.parent = p

    def get_next_node(self, node):
        if node.right is not None:
            # print('node right is not none')
            return self.get_minimum(node.right)
        p = x.parent
        while p is not None and p != p.parent.left:
            p = p.parent
        return p.parent

    def get_minimum(self, node):
        x = node
        # print('find1 :', x.key)
        while x.left is not None:
            x = x.left
            # print('find2 :', x.key)
        return x

    def print_inorder(self):
        self.inorder = []
        self.inorder_traverse(self.root)
        print(' ' + ' '.join(map(str, self.inorder)))

    def print_preorder(self):
        self.preorder = []
        self.preorder_traverse(self.root)
        print(' ' + ' '.join(map(str, self.preorder)))

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

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

tree = Tree()
m = int(input())
for i in range(m):
    line = input().split()
    if line[0] == 'print':
        # print('root', str(tree.root.key))
        tree.print_inorder()
        tree.print_preorder()
        # print('root:(30)', tree.root.key)
        # print('root.left(17):', tree.root.left.key)
        # print('root.left.left(X):', tree.root.left.left.key)
        # print('root.left.right(X):', tree.root.left.right.key)
        # print('-----------------')
    elif line[0] == 'insert':
        key = int(line[1])
        tree.insert(Node(key))
    elif line[0] == 'find':
        key = int(line[1])
        if tree.find(key):
            print('yes')
        else:
            print('no')
    elif line[0] == 'delete':
        
        # print("current tree----")
        # print(tree.root.key)
        # print(tree.root.left.key)
        # print(tree.root.left.right.key)
        # print(tree.root.left.right.parent.key)
        # print("current tree----")
        key = int(line[1])
        # print('delete', str(key))
        node = tree.find(key)
        # print('node.key', node.key)
        tree.delete(node)



# print('root.left.right:', tree.root.left.right.left.key)
# print('root:', tree.root.left.right.right.key)

Submission status: Runtime Error

Solution code:
import sys
class Tree():
    def __init__(self):
        self.root = None
    def insert(self, key):
        z = Node(key)
        y = None
        x = self.root
        while x:
            y = x
            if z.key < x.key:
                x = x.left
            else:
                x = x.right
        z.parent = y
        if y == 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 and x.key != key:
            if x.key < key:
                x = x.right
            else:
                x = x.left
        return x
    def delete(self, key):
        z = self.find(key)
        y = successor(z) if z.left and z.right else z
        x = y.left if y.left else y.right

        if x:
            x.parent = y.parent
        if y.parent == None:
            self.root = x 
        elif y == y.parent.left:
            y.parent.left = x
        else:
            y.parent.right = x
        if y != z:
            z.key = y.key
    def successor(x):
        if x.right:
            return minimum(x.right)
        y = x.parent
        while y and x == y.right:
            x = y
            y = y.parent
        return y

    def minimum(x):
        while x.left:
            x = x.left
        return x
    
    def print(self):
        print('',' '.join(map(str, self.root.inwalk())))
        print('',' '.join(map(str, self.root.prewalk())))
    
class Node():
    def __init__(self, key):
        self.key = key
        self.parent = self.left = self.right = None
    def prewalk(self):
        ret = [self.key]
        if self.left:
            ret += self.left.prewalk()
        if self.right:
            ret += self.right.prewalk()
        return ret
    def inwalk(self):
        ret = []
        if self.left:
            ret += self.left.inwalk()
        ret += [self.key]
        if self.right:
            ret += self.right.inwalk()
        return ret
tree = Tree()
n = sys.stdin.readline()
for line in sys.stdin:
    if line[0] == 'i':
        tree.insert(int(line.split()[1]))
    elif line[0] == 'f':
        print('yes' if tree.find(int(line.split()[1])) else 'no')
    elif line[0] == 'd':
        tree.delete(int(line.split()[1]))            
    else:
        tree.print()