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.

Solution in C++ (judge verdict: Accepted)

#include <cstdio>
#include <cstdlib>
#include <iostream>
#include <string>

using namespace std;

struct node{

    int key;
    node *right, *left, *parent;

};

node *NIL, *root;

void insert( int k ){

    node *y = NIL;
    node *x = root;
    node *z;

    z = ( node * )malloc( sizeof(node) );

    z -> key = k;
    z -> left = NIL;
    z -> right = NIL;

    while( x != NIL ){

        y = x;

        if( z -> key < x -> key ){

            x = x -> left;

        } else {

            x = x -> right;

        }

    }

    z -> parent = y;

    if( y == NIL ){

        root = z;

    } else {

        if( z-> key < y -> key ){

            y -> left = z;

        } else{

            y -> right = z;

        }

    }

}

node * find( node *u, int k ){

    while( u != NIL && k != u->key ){

        if( k < u->key ){

            u = u->left;

        } else {

            u = u->right;

        }

    }

    return u;

}

node * tree_minimum( node *x ){

    while( x->left != NIL ){

        x = x-> left;

    }

    return x;

}

node * getsuccessor( node *x ){

    if( x->right != NIL ) return tree_minimum( x->right );

    node *y = x->parent;

    while( y != NIL && x == y->right ){

        x = y;
        y = y->parent;

    }

    return y;

}

void tree_delete( int k ){

    node *t = find( root, k);

    node *x, *y;    //y:削除する対象、x:その子

    //削除する節点を決める

    if( t->left == NIL || t->right == NIL ){

        y = t;  //子なし、１個の場合

    } else {

        //子２の場合

        y = getsuccessor(t);

    }

    if( y->left != NIL ){

        x = y->left;

    }else{

        x = y->right;

    }

    if( x != NIL ){

        x->parent = y->parent;

    }

    if( y->parent == NIL ){

        root = x;

    } else {

        if( y == y->parent->left ){

            y->parent->left = x;

        } else {

            y->parent->right = x;

        }

    }

    if( y != t ){

        t->key = y->key;

    }

    free(y);

}

void inorder( node *u ){

    if( u == NIL ) return;
    inorder( u -> left );
    printf(" %d", u -> key );
    inorder( u -> right );

}

void preorder( node *u ){

    if( u == NIL ) return;
    printf(" %d", u -> key );
    preorder( u -> left );
    preorder( u -> right );   

}


int main(){

    int n, i, x;
    string com;

    scanf("%d", &n);

    for( i = 0 ; i < n ; i++ ){

        cin >> com;

        if( com == "insert" ){

            scanf("%d", &x);
            insert(x);

        } else if( com == "print" ){

            inorder( root );
            printf("\n");
            preorder( root );
            printf("\n");

        } else if( com == "find" ){

            scanf("%d", &x);
            node *t = find( root, x);

            if( t == NIL ) printf("no\n");
            else printf("yes\n");

        } else {

            scanf("%d", &x);

            tree_delete(x);
            

        }

    }

    return 0;

}