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 JavaScript (judge verdict: Runtime Error)

//config = { input: 'tmp', newline: '\r\n' }; // win
config = { input: '/dev/stdin', newline: '\n' }; // linux

function Tree() {
  this.root = null;
  this.node = {};
}
Tree.prototype.insert = function (val) {
  var z, y, x;
  z = {'left': null, 'right': null, 'key': val, 'parent': null};
  this.node[val] = z;
  y = null;
  x = this.root;
  while (x !== null) {
    y = x;
    if (z.key < x.key) x = x.left;
    else x = x.right;
  }
  z.parent = y;

  if (y === null) this.root = z;
  else if (z.key < y.key) y.left = z;
  else y.right = z;
}
Tree.prototype.find = function (val) {
  return (this.node.hasOwnProperty(val));
}
Tree.prototype.delete = function (val) {
  var node, parent, child, next;
  node = this.node[val];
  if (node === this.root) {
    this.root = null;
    delete this.node[val];
    return;
  }
  parent = node.parent;
  if (!node.left && !node.right) {
    if (parent.left === node) parent.left = null;
    else parent.right = null;
    delete this.node[val];
  } else if (!node.left || !node.right) {
    if (node.left) child = node.left;
    else child = node.right;
    child.parent = parent;
    if (parent.left === node) parent.left = child;
    else parent.right = child;
    delete this.node[val];
  } else {
    next = this.next(node.key);
    node.key = next;
    this.delete(next);
  }
}
Tree.prototype.next = function(val) {
  var node, parent;
  node = this.node[val];
  if (node.right) {
    node = node.right;
    while (node.left) node = node.left;
    return node.key;
  }
  while (true) {
    parent = node.parent;
    if (!parent) return null;
    if (parent.left === node) return parent.key;
    node = parent;
  }
}
Tree.prototype.printTree = function() {
  function p(node, depth) {
    var indent = '', i;
    for (i = 0; i < depth; i++) indent = indent + '  ';
    if (node === null) {
      console.log(indent + 'NIL');
      return;
    }
    console.log(indent + node.key);
    p(node.left, depth+1);
    p(node.right, depth+1);
  }
  p(this.root, 0);
}
Tree.prototype.print = function() {
  function inorder(node) {
    var res = [];
    if (node === null) return res;
    res = res.concat(inorder(node.left));
    res.push(node.key);
    res = res.concat(inorder(node.right))
    return res;
  }
  function preorder(node) {
    var res = [];
    if (node === null) return res;
    res.push(node.key);
    res = res.concat(preorder(node.left));
    res = res.concat(preorder(node.right));
    return res;
  }
  console.log(' ' + inorder(this.root).join(' '));
  console.log(' ' + preorder(this.root).join(' '));
}

si = require('fs').createReadStream(config.input, {encoding: 'ascii'});
rl = require('readline').createInterface({
  input: si, output: process.stdout});

t = new Tree();

rl.on('line', function (line) {
  var inst;
  inst = line.split(' ');
  if (inst[0] === 'insert') {
    t.insert(parseInt(inst[1], 10));
  } else if (inst[0] === 'find') {
    console.log(t.find(parseInt(inst[1], 10)) ? 'yes' : 'no');
  } else if (inst[0] === 'delete') {
    t.delete(parseInt(inst[1], 10));
  } else if (inst[0] === 'print') {
    //t.printTree();
    t.print();
  }
});