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 PHP (judge verdict: Wrong Answer)

<?php
solve1();

// 自力解
function solve1(){
	$n = (int)trim(fgets(STDIN));

	$list = [];
	for ($i=0; $i < $n; $i++) { 
		$input = explode(' ', trim(fgets(STDIN)));
		if ($input[0] === 'insert') {
			$node = new BTreeNode((int)$input[1]);
			$list[$node->getId()] = $node;
			insertNode($list, $node);
		}elseif ($input[0] === 'delete') {
			$list = deleteNode($list, (int)$input[1]);
			// var_dump($list);
		}elseif ($input[0] === 'find') {
			if (findNode($list, (int)$input[1])) {
				echo 'yes' . PHP_EOL;
			}else{
				echo 'no' . PHP_EOL;
			}
		}else{
			// $root = getRoot($list);
			// if ($root != NULL) {
			// 	inorderWalk($list, $root);
			// 	echo PHP_EOL;
			// 	preorderWalk($list, $root);
			// 	echo PHP_EOL;
			// }else{
			// 	echo PHP_EOL;
			// 	echo PHP_EOL;
			// }
			var_dump($list);
		}
	}
}

function getRoot($list){
	$p = NULL;
	if (count($list) > 0) {
		$p = $list[array_keys($list)[0]]->getId();
		while (true) {
			$tmp = $list[$p]->getParentId();
			if ($tmp === NULL) {
				break;
			}
			$p = $tmp;
		}
	}
	return $p;
}
function insertNode($list, $node){
	$parent = NULL;
	$cur = getRoot($list);
	while ($cur != NULL) {
		$parent = $cur;
		if ($node->getId() < $list[$parent]->getId()) {
			$cur = $list[$parent]->getLeft();
		}else{
			$cur = $list[$parent]->getRight();
		}
	}
	if ($parent !== $node->getId()) {
		$node->setParentId($parent);
		if ($parent !== NULL) {
			if ($node->getId() < $list[$parent]->getId()) {
				$list[$parent]->setLeft($node->getId());
			}else{
				$list[$parent]->setRight($node->getId());
			}
		}
	}

}

function findNode($list, $target){
	$cur = getRoot($list);
	while ($cur != NULL) {
		if ($list[$cur]->getId() === $target) {
			break;
		}
		$parent = $cur;
		if ($target < $list[$parent]->getId()) {
			$cur = $list[$parent]->getLeft();
		}else{
			$cur = $list[$parent]->getRight();
		}
	}
	return ($cur != NULL);
}

function deleteNode($list, $target){
	if (isset($list[$target])) {
		$children = $list[$target]->getChildren();
		if (count($children) < 2) {
			$successor = $target;
		} else {
			$successor = getSuccessor($list, $target);
		}
		$parent = $list[$successor]->getParentId();

		if ($list[$successor]->hasLeft()) {
			$child = $list[$successor]->getLeft();
		}else{
			$child = $list[$successor]->getRight();
		}
		if ($child !== NULL) {
			$list[$child]->setParentId($parent);
		}

		if ($parent == NULL) {
			# code...
		} elseif ($successor === $list[$parent]->getLeft()) {
			$list[$parent]->setLeft($child);
		}else{
			$list[$parent]->setRight($child);
		}

		if ($successor !== $target) {
			$list[$target]->setId($successor);
			$list[$successor] = $list[$target];
			if ($list[$successor]->hasLeft()) {
				$left = $list[$successor]->getLeft();
				$list[$left]->setParentId($successor);
			}
			if ($list[$successor]->hasRight()) {
				$right = $list[$successor]->getRight();
				$list[$right]->setParentId($successor);
			}
		}
		unset($list[$target]);
	}
	return $list;
}

function getSuccessor($list, $id){
	if ($list[$id]->hasRight()) {
		return getMinimum($list, $list[$id]->getRight());
	}
	$parent = $list[$id]->getParentId();
	while ($parent !== NULL && $id === $list[$parent]->getRight()) {
		$id = $parent;
		$parent = $parent->getParentId();
	}
	return $parent;
}

function getMinimum($list, $id){
	while ($list[$id]->hasLeft()) {
		$id = $list[$id]->getLeft();
	}
	return $id;
}

function preorderWalk($list, $id){
	echo ' ' . $id;
	if ($list[$id]->hasLeft()) {
		preorderWalk($list, $list[$id]->getLeft());
	}
	if ($list[$id]->hasRight()) {
		preorderWalk($list, $list[$id]->getRight());
	}
}

function inorderWalk($list, $id){
	if ($list[$id]->hasLeft()) {
		inorderWalk($list, $list[$id]->getLeft());
	}
	echo ' ' . $id;
	if ($list[$id]->hasRight()) {
		inorderWalk($list, $list[$id]->getRight());
	}
}

class BTreeNode
{
	private $id;
	private $depth = 0;
	private $height = 0;
	private $parent_id = NULL;
	private $left = NULL;
	private $right = NULL;

	function __construct($id)
	{
		$this->id = $id;
	}
	function setParentId($p_id){
		$this->parent_id = $p_id;
	}
	function setLeft($l_id){
		$this->left = $l_id;
	}
	function setRight($r_id){
		$this->right = $r_id;
	}
	function setId($id){
		$this->id = $id;
	}
	function getId(){
		return $this->id;
	}
	function getParentId(){
		return $this->parent_id;
	}
	function getLeft(){
		return $this->left;
	}
	function getRight(){
		return $this->right;
	}
	function hasChild(){
		return ($this->left !== NULL) || ($this->right !== NULL);
	}
	function getChildren(){
		$children = [];
		if ($this->hasLeft()) {
			$children[] = $this->left;
		}
		if ($this->hasRight()) {
			$children[] = $this->right;
		}
		return $children;
	}
	function getAnotherChild($c_id){
		$c = NULL;
		if ($this->getLeft() === $c_id) {
			$c = $this->getRight();
		}elseif ($this->getRight() === $c_id) {
			$c = $this->getLeft();
		}
		return $c;
	}
	function hasLeft(){
		return $this->left !== NULL;
	}
	function hasRight(){
		return $this->right !== NULL;
	}
	function setDepth($d){
		$this->depth = $d;
	}
	function addDepth(){
		$this->depth += 1;
	}
	function getDepth(){
		return $this->depth;
	}
	function setHeight($h){
		$this->height = $h;
	}
	function getHeight(){
		return $this->height;
	}
}