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)

# ????????¢?´¢??¨
class Tree
	# ????????????
	class Node
		def initialize(key, data)
			@key = key
			@data = data
			@left = nil
			@right = nil
		end
		attr_accessor :key, :data, :left, :right
	end
	
	def initialize
		@root = nil
	end
	
	# ????????¢??°
	private

	# ??¢?´¢
	def search(node, key)
		while node
			if key == node.key
				return node
			elsif key < node.key
				node = node.left
			else
				node = node.right
			end
		end
	end
	
	# ?????\
	def insert!(node, key, data)
		if node == nil
			return Node.new(key, data)
		elsif key == node.key
			node.data = data
		elsif key < node.key
			node.left = insert!(node.left, key, data)
		else
			node.right = insert!(node.right, key, data)
		end
		node
	end
	
	# ????°?????????¢???
	def search_min(node)
		node = node.left while node.left
		node
	end
	
	# ?????§????????¢???
	def search_max(node)
		node = node.right while node.right
		node
	end
	
	# ????°???????????????????
	def delete_min!(node)
		return node.right unless node.left
		node.left = delete_min!(node.left)
		node
	end
	
	# ??????
	def delete!(node, key)
		data = nil
		if node
			if key == node.key
				data = node.data
				if node.left == nil
					return node.right, data
				elsif node.right == nil
					return node.left, data
				else
					min_node = search_min(node.right)
					node.key = min_node.key
					node.data = min_node.data
					node.right = delete_min!(node.right)
				end
			elsif key < node.key
				node.left, data = delete!(node.left, key)
			else
				node.right, data = delete!(node.right, key)
			end
		end
		return node, data
	end

	# ???????????¢?´¢
	def precedingOrderSearch(node, &func)
		if node
			func.call(node.key, node.data)
			precedingOrderSearch(node.left, &func)
			precedingOrderSearch(node.right, &func)
		end
	end
	# ???????????¢?´¢
	def afterLineOrderSearch(node, &func)
		if node
			afterLineOrderSearch(node.left, &func)
			afterLineOrderSearch(node.right, &func)
			func.call(node.key, node.data)
		end
	end
	#???????????¢?´¢
	def centerOrderSearch(node, &func)
		if node
			centerOrderSearch(node.left, &func)
			func.call(node.key, node.data)
			centerOrderSearch(node.right, &func)
		end
	end


	# ??¬???????????????
	public

	# ??¢?´¢
	def find(key)
		node = search(@root, key)
		if node
			return	node.data
		else
			return	nil
		end
	end
	
	# ?????\ (??´??°)
	def insert(key, value)
		@root = insert!(@root, key, value)
	end
	
	# ??????
	def delete_key(key)
		@root, data = delete!(@root, key)
		data
	end
	
	# ????°????????±???????
	def min
		if @root
			node = search_min(@root)
			if node
				return node.key, node.data
			end
		end
	end
	
	# ?????§???????±???????
	def max
		if @root
			node = search_max(@root)
			if node
				return node.key, node.data
			end
		end
	end
	
	# ????????????
	def precedingCrawl(&func)
		precedingOrderSearch(@root, &func)
	end

# ????????????
def afterLineCrawl(&func)
	afterLineOrderSearch(@root, &func)
end

# ????????????
def centerCrawl(&func)
	centerOrderSearch(@root, &func)
end


def inspect
	sprintf("#<Tree:%#x>", self.object_id)
end
end
n = gets.to_i
head = nil

n.times do
	num = gets.to_s.chomp!
	if num == "print"
		center = []
		head.centerCrawl do |key, value|
			center << key
		end
		preceding = []
		head.precedingCrawl do |key, value|
			preceding << key
		end

		puts " #{center.join(" ")}"
		puts " #{preceding.join(" ")}"
	else
		num = num.split
		if num[0].to_s == "insert"
			head = Tree.new unless head
			head.insert(num[1].to_i,"dummy")
		elsif num[0].to_s == "delete"
			head.delete_key num[1].to_i 
		else
			puts head.find(num[1].to_i) ?  "yes" : "no"
		end

	end

end