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 Ruby (judge verdict: Accepted)

# ALDS1_8_C: Binary Search Tree 3: Delete

class BinaryTree
  def initialize
    @root = NIL
  end

  def insert(key)
    parent = NIL
    node   = @root
    while node != NIL
      parent = node 
      node = key < node.key ? node.left : node.right
    end

    new_node = Node.new key
    if parent == NIL
      @root = new_node
    elsif key < parent.key
      parent.set_left new_node
    else
      parent.set_right new_node
    end
  end

  def find(key)
    node = @root
    while node != NIL
      break if node.key == key
      node = key < node.key ? node.left : node.right
    end
    node
  end

  def delete(key)
    target = find key
    return if target == NIL

    if target.has_children?
      next_node = target.right.minimum_leaf
      target.key = next_node.key
      target = next_node
    end

    child = target.has_left? ? target.left : target.right
    if target.on_left?
      target.parent.set_left child
    else
      target.parent.set_right child
    end
  end

  def has?(key)
    find(key) != NIL
  end

  def keys_by_preorder(node = @root)
    return [] if node == NIL
    left_keys  = keys_by_preorder(node.left)
    right_keys = keys_by_preorder(node.right)
    [node.key] + left_keys + right_keys
  end

  def keys_by_inorder(node = @root)
    return [] if node == NIL
    left_keys  = keys_by_inorder(node.left)
    right_keys = keys_by_inorder(node.right)
    left_keys + [node.key] + right_keys
  end

  private

    class Node
      attr_accessor :key
      attr_reader :parent, :left, :right

      def initialize(key, parent = NIL, left = NIL, right = NIL)
        @key = key
        set_parent parent, nil
        set_left left
        set_right right
      end

      def set_left(node)
        @left = node
        return if node == NIL
        node.set_parent self, :left
      end
      
      def set_right(node)
        @right = node
        return if node == NIL
        node.set_parent self, :right
      end

      def on_left?
        @on == :left
      end

      def has_children?
        has_left? && has_right?
      end

      def has_left?
        @left != NIL
      end

      def has_right?
        @right != NIL
      end
      
      def minimum_leaf
        node = self
        node = node.left while node.left != NIL
        node
      end

      protected
        def set_parent(node, position)
          @parent = node
          @on = position
        end
    end

    NIL = Node.new(nil).tap do |n|
      [:parent, :left, :right].each do |name|
        define_method(name) { self }
      end
    end
end

tree = BinaryTree.new
n_commands = gets.to_i

n_commands.times do
  command = gets.chomp
  case command
  when /insert (-?\d+)/
    key = $1.to_i
    tree.insert key
  when /find (-?\d+)/
    key = $1.to_i
    puts tree.has?(key) ? 'yes' : 'no'
  when /delete (-?\d+)/
    key = $1.to_i
    tree.delete key
  when /print/
    puts ' ' << tree.keys_by_inorder.join(' ')
    puts ' ' << tree.keys_by_preorder.join(' ')
  end
end