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.



Sample input:
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:
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

Submission status: Runtime Error

Solution code:
class BinaryTreeNode():
    def __init__(self, val, parent=None, left=None, right=None):
        self.parent = parent
        self.left = None
        self.right = None
        self.val = val

    def get_child_num(self):
        num = 0
        if self.left != None: num += 1
        if self.right != None: num += 1
        return num

    def get_successor(self):
        x = self
        if x.right != None:
            return self.get_minimum(x.right)

        y = x.parent
        while y != None and x == y.right:
            x = y
            y = y.parent
        return y

    def get_minimum(self):
        x = self
        while x.left != None:
            x = x.left
        return x

class BinarySearchTree():
    def __init__(self):
        self.root = None

    def insert(self, val):
        y = None
        x = self.root
        while x != None:
            y = x
            if val < x.val:
                x = x.left
            else:
                x = x.right
        node = BinaryTreeNode(val=val, parent=y)

        if y == None:
            self.root = node
        elif node.val < y.val:
            y.left = node
        else:
            y.right = node

    def find(self, val):
        x = self.root
        while x != None:
            if x.val == val:
                return x
            elif x.val < val:
                x = x.right
            else:
                x = x.left
        return None

    def delete(self, val):
        z = self.find(val)
        if z == None: return

        y = None
        if z.get_child_num() < 2:
            y = z
        else:
            y = z.get_successor()

        x = None
        if y.left != None:
            x = y.left
        else:
            x = y.right

        if x != None:
            x.parent = y.parent

        if y.parent == None:
            self.root = x
        elif y == y.parent.left:
            y.parent.left = x
        else:
            y.parent.right = x

        if y != z:
            x.key = y.key

    def preorder(self):
        self.preorder_list = []
        self.preorder_bfs(self.root)
        return self.preorder_list

    def preorder_bfs(self, u):
        if u == None: return
        self.preorder_list.append(u.val)
        self.preorder_bfs(u.left)
        self.preorder_bfs(u.right)

    def inorder(self):
        self.inorder_list = []
        self.inorder_dfs(self.root)
        return self.inorder_list

    def inorder_dfs(self, u):
        if u == None: return
        self.inorder_dfs(u.left)
        self.inorder_list.append(u.val)
        self.inorder_dfs(u.right)

def print_elements(arr):
    print(' ' + ' '.join([str(item) for item in arr]))

m = int(input())
bst = BinarySearchTree()
for i in range(m):
    op = input()
    if op.startswith('insert'):
        num = int(op[7:])
        bst.insert(num)
    elif op.startswith('delete'):
        num = int(op[7:])
        bst.delete(num)
    elif op.startswith('find'):
        num = int(op[5:])
        if bst.find(num):
            print('yes')
        else:
            print('no')
    else:
        print_elements(bst.inorder())
        print_elements(bst.preorder())

Submission status: Runtime Error

Solution code:
import sys

tree={}
np = -1

home=0
tree[home]=[None, None, None]

def search(p, x):
    node_pos=[None,None]
    while p != None:
        tmp = tree[p]
        if tmp[0] == x:
            node_pos[0] = p
            return node_pos
        node_pos[1] = p
        if x < tmp[0]:
            p = tmp[1]
        else:
            p = tmp[2]
    return node_pos

def node(x):
    global np
    np += 1
    tree[np] = [x, None, None]
    return np

def insert(p, x):
    if p == None or np == -1: return node(x)
    tmp = tree[p]
    if x== tmp[0]: return p
    elif x<tmp[0]:
        tree[p][1]=insert(tmp[1],x)
    else:
        tree[p][2]=insert(tmp[2],x)
    return p

def deletenode(p, parent, child=None):
        if tree[parent][1]==p:
            tree[parent][1] = child
        elif tree[parent][2]==p:
            tree[parent][2] = child
        del tree[p]

def searchmin(p):
    if tree[p][1]!=none:
        p = tree[p][1]
    return p

def delete(x):
    p, parent = search(0,x)
    if tree[p][1:3]==[None,None]:
        deletenode(p,parent)
    elif tree[p][1]==None:
        deletenode(p, parent, tree[p][2])
    elif tree[p][2]==None:
        deletenode(p, parent, tree[p][1])
    else:
        p1=searchmin(tree[p][2])
        if tree[parent][1]==p:
            tree[parent][1] = p1
        elif tree[parent][2]==p:
            tree[parent][2] = p1
        tree[p1][1]=tree[p][1]
        tree[p1][2]=tree[p][2]
        del tree[p]
    return

def preorder(p):
    if p == None: return []
    p1, p2 = tree[p][1:3]
    return [tree[p][0]] + preorder(p1) + preorder(p2)

def inorder(p):
    if p == None: return []
    p1, p2 = tree[p][1:3]
    return inorder(p1) + [tree[p][0]] +inorder(p2)

n = int(input())
i = 0
while i<n:
    s = raw_input()
    if s[0]=='i':
        insert(0,int(s[7:]))
    elif s[0]=='f':
        if search(0,int(s[5:]))[0]!=None: print 'yes'
        else print 'no'
    elif s[0]=='d':
        delete(0,int(s[7:]))
    elif s[0]=='p':
        print ' ' + ' '.join(map(str, inorder(home)))
        print ' ' + ' '.join(map(str, preorder(home)))
    i += 1

Submission status: Runtime Error

Solution code:
import sys

tree={}
np = -1

home=0
tree[home]=[None, None, None]

def search(p, x):
    node_pos=[None,None]
    while p != None:
        tmp = tree[p]
        if tmp[0] == x:
            node_pos[0] = p
            return node_pos
        node_pos[1] = p
        if x < tmp[0]:
            p = tmp[1]
        else:
            p = tmp[2]
    return node_pos

def node(x):
    global np
    np += 1
    tree[np] = [x, None, None]
    return np

def insert(p, x):
    if p == None or np == -1: return node(x)
    tmp = tree[p]
    if x== tmp[0]: return p
    elif x<tmp[0]:
        tree[p][1]=insert(tmp[1],x)
    else:
        tree[p][2]=insert(tmp[2],x)
    return p

def deletenode(p, parent, child=None):
        if tree[parent][1]==p:
            tree[parent][1] = child
        elif tree[parent][2]==p:
            tree[parent][2] = child
        del tree[p]

def searchmin(p):
    if tree[p][1]!=none:
        p = tree[p][1]
    return p

def delete(x):
    p, parent = search(0,x)
    if tree[p][1:3]==[None,None]:
        deletenode(p,parent)
    elif tree[p][1]==None:
        deletenode(p, parent, tree[p][2])
    elif tree[p][2]==None:
        deletenode(p, parent, tree[p][1])
    else:
        p1=searchmin(tree[p][2])
        if tree[parent][1]==p:
            tree[parent][1] = p1
        elif tree[parent][2]==p:
            tree[parent][2] = p1
        tree[p1][1]=tree[p][1]
        tree[p1][2]=tree[p][2]
        del tree[p]
    return

def preorder(p):
    if p == None: return []
    p1, p2 = tree[p][1:3]
    return [tree[p][0]] + preorder(p1) + preorder(p2)

def inorder(p):
    if p == None: return []
    p1, p2 = tree[p][1:3]
    return inorder(p1) + [tree[p][0]] +inorder(p2)

n = int(input())
i = 0
while i<n:
    s = raw_input()
    if s[0]=='i':
        insert(0,int(s[7:]))
    elif s[0]=='f':
        if search(0,int(s[5:]))[0]!=None: print 'yes'
        else: print 'no'
    elif s[0]=='d':
        delete(int(s[7:]))
    elif s[0]=='p':
        print ' ' + ' '.join(map(str, inorder(home)))
        print ' ' + ' '.join(map(str, preorder(home)))
    i += 1

Submission status: WA: Presentation Error

Solution code:
#!/usr/bin/env python3
# -*- coding: utf-8 -*-

"""
input:
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

output: finded + in_order + pre_order
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

"""

import sys
import copy


class Node(object):
    def __init__(self, data):
        self.data = data
        self.left, self.right = None, None

    def insert(self, data):
        """
        insert data according to BST rules
        """
        if data < self.data:
            if not self.left:
                self.left = Node(data)
            else:
                self.left.insert(data)
        # insert duplicate value to right
        else:
            if not self.right:
                self.right = Node(data)
            else:
                self.right.insert(data)

        return self.data

    def find(self, data, parent=None):
        """
        find node with given data
        tree walk as insert goes
        """
        if data < self.data:
            if not self.left:
                return None, None
            return self.left.find(data=data, parent=self)
        elif data > self.data:
            if not self.right:
                return None, None
            return self.right.find(data=data, parent=self)
        else:
            return self, parent

    def children_count(self):
        """
        for choosing node deleting strategy
        """
        cnt = 0
        if self.left:
            cnt += 1
        if self.right:
            cnt += 1
        return cnt

    def delete(self, data):
        """
        delete node with given data
        """
        node, parent = self.find(data)
        if node:
            children_count = node.children_count()
            if children_count == 0:
                # delete reference to parent
                if parent.left is node:
                    parent.left = None
                else:
                    parent.right = None
                del node
            elif children_count == 1:
                # node's son becomes parents' son
                if node.left:
                    n = node.left
                else:
                    n = node.right
                if parent:
                    if parent.left is node:
                        parent.left = n
                    else:
                        parent.right = n
                del node
            else:
                # current node has two real children
                # while the real successor couldn't have two real children
                successor = node.right
                while successor.left:
                    successor = successor.left
                copy_data = successor.data
                self.delete(copy_data)
                node.data = copy_data


def pre_order(node):
    if node:
        print(node.data, end=' ')
        pre_order(node.left)
        pre_order(node.right)
    return None


def in_order(node):
    if node:
        in_order(node.left)
        print(node.data, end=' ')
        in_order(node.right)
    return None


def action(command, content):
    # start all action from tree_root -- insert, find, delete
    if command.startswith('in'):
        tree_root.insert(int(content))

    elif command.startswith('fi'):
        if tree_root.find(int(content)) == (None, None):
            print('no')
        else:
            print('yes')

    elif command.startswith('de'):
        tree_root.delete(int(content))

    # print tree walk
    else:
        print(' ', end='')
        in_order(tree_root)
        print('')
        print(' ', end='')
        pre_order(tree_root)
        print('')

    return None


if __name__ == '__main__':
    _input = sys.stdin.readlines()
    array_length = int(_input[0])
    command_list = list(map(lambda x: x.split(), _input[1:]))
    # assert len(command_list) == array_length

    flag, tree_root = False, None
    for each in command_list:
        command, content = each[0], each[-1]
        if (not flag) and command.startswith('in'):
            tree_root = Node(data=int(content))
            flag = True
            continue
        action(command, content)

Submission status: WA: Presentation Error

Solution code:
#!/usr/bin/env python3
# -*- coding: utf-8 -*-

"""
input:
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

output: finded + in_order + pre_order
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

"""

import sys
import copy


class Node(object):
    def __init__(self, data):
        self.data = data
        self.left, self.right = None, None

    def insert(self, data):
        """
        insert data according to BST rules
        """
        if data < self.data:
            if not self.left:
                self.left = Node(data)
            else:
                self.left.insert(data)
        # insert duplicate value to right
        else:
            if not self.right:
                self.right = Node(data)
            else:
                self.right.insert(data)

        return self.data

    def find(self, data, parent=None):
        """
        find node with given data
        tree walk as insert goes
        """
        if data < self.data:
            if not self.left:
                return None, None
            return self.left.find(data=data, parent=self)
        elif data > self.data:
            if not self.right:
                return None, None
            return self.right.find(data=data, parent=self)
        else:
            return self, parent

    def children_count(self):
        """
        for choosing node deleting strategy
        """
        cnt = 0
        if self.left:
            cnt += 1
        if self.right:
            cnt += 1
        return cnt

    def delete(self, data):
        """
        delete node with given data
        """
        node, parent = self.find(data)
        if node:
            children_count = node.children_count()
            if children_count == 0:
                # delete reference to parent
                if parent.left is node:
                    parent.left = None
                else:
                    parent.right = None
                del node
            elif children_count == 1:
                # node's son becomes parents' son
                if node.left:
                    n = node.left
                else:
                    n = node.right
                if parent:
                    if parent.left is node:
                        parent.left = n
                    else:
                        parent.right = n
                del node
            else:
                # current node has two real children
                # while the real successor couldn't have two real children
                successor = node.right
                while successor.left:
                    successor = successor.left
                copy_data = successor.data
                self.delete(copy_data)
                node.data = copy_data


def pre_order(node):
    if node:
        print(node.data, end=' ')
        pre_order(node.left)
        pre_order(node.right)
    return None


def in_order(node):
    if node:
        in_order(node.left)
        print(node.data, end=' ')
        in_order(node.right)
    return None


def action(command, content):
    # start all action from tree_root -- insert, find, delete
    if command.startswith('in'):
        tree_root.insert(int(content))

    elif command.startswith('fi'):
        if tree_root.find(int(content)) == (None, None):
            print('no')
        else:
            print('yes')

    elif command.startswith('de'):
        tree_root.delete(int(content))

    # print tree walk
    else:
        print(' ', end='')
        in_order(tree_root)
        print('', end='\n')
        print(' ', end='')
        pre_order(tree_root)
        print('', end='\n')

    return None


if __name__ == '__main__':
    _input = sys.stdin.readlines()
    array_length = int(_input[0])
    command_list = list(map(lambda x: x.split(), _input[1:]))
    # assert len(command_list) == array_length

    flag, tree_root = False, None
    for each in command_list:
        command, content = each[0], each[-1]
        if (not flag) and command.startswith('in'):
            tree_root = Node(data=int(content))
            flag = True
            continue
        action(command, content)

Submission status: WA: Presentation Error

Solution code:
import sys
n_order = int(raw_input())


class node:

    def __init__(self, num, parent):
        self.num = num
        self.left = None
        self.right = None
        self.parent = None


def insert(num, c_node):
    if num >= c_node.num:
        if c_node.right == None:
            # print num, c_node.num, "right"
            c_node.right = node(num, c_node)
            c_node.right.parent = c_node
        elif c_node.right != None:
            insert(num, c_node.right)
    elif num < c_node.num:
        if c_node.left == None:
            c_node.left = node(num, c_node)
            c_node.left.parent = c_node
            # print num, c_node.num, "left"
        elif c_node.left != None:
            insert(num, c_node.left)


def c_print(c_node):
    sys.stdout.write(str(c_node.num) + " ")
    if c_node.left != None:
        c_print(c_node.left)
    if c_node.right != None:
        c_print(c_node.right)


def p_print(c_node):
    if c_node.left != None:
        p_print(c_node.left)
    sys.stdout.write(str(c_node.num) + " ")
    if c_node.right != None:
        p_print(c_node.right)


def find(num, c_node):
    if num == c_node.num:
        print "yes"
    elif num > c_node.num:
        if c_node.right == None:
            print "no"
        elif c_node.right != None:
            find(num, c_node.right)
    elif num < c_node.num:
        if c_node.left == None:
            print "no"
        elif c_node.left != None:
            find(num, c_node.left)


def find_return(num, c_node):
    if num == c_node.num:
        return c_node
    elif num > c_node.num:
        if c_node.right == None:
            return None
        elif c_node.right != None:
            return find_return(num, c_node.right)
    elif num < c_node.num:
        if c_node.left == None:
            return None
        elif c_node.left != None:
            return find_return(num, c_node.left)


def find_midorder_return(c_node):
    if c_node.left == None:
        return c_node
    else:
        return find_midorder_return(c_node.left)


def delete(num, c_node):
    del_node = find_return(num, c_node)
    if del_node.left == None and del_node.right == None:
        if del_node.parent == None:
            c_node = None
        elif del_node.parent.num > del_node.num:
            del_node.parent.left = None
        elif del_node.parent.num < del_node.num:
            del_node.parent.right = None
    elif del_node.left == None:
        if del_node.parent == None:
            c_node = del_node.right
        elif del_node.parent.num > del_node.num:
            del_node.parent.left = del_node.right
            del_node.right.parent = del_node.parent
        elif del_node.parent.num < del_node.num:
            del_node.parent.right = del_node.right
            del_node.right.parent = del_node.parent
    elif del_node.right == None:
        if del_node.parent == None:
            c_node = del_node.left
        elif del_node.parent.num > del_node.num:
            del_node.parent.left = del_node.left
            del_node.left.parent = del_node.parent
        elif del_node.parent.num < del_node.num:
            del_node.parent.right = del_node.left
            del_node.left.parent = del_node.parent
    else:
        deep_left_node = find_midorder_return(del_node)
        if deep_left_node.right != None:
            if del_node.parent == None:
                pass
            elif deep_left_node.parent.num > deep_left_node.num:
                deep_left_node.parent.left = deep_left_node.right
                deep_left_node.right.parent = deep_left_node.parent
            elif del_node.parent.num < deep_left_node.num:
                deep_left_node.parent.right = deep_left_node.right
                deep_left_node.right.parent = deep_left_node.parent
        deep_left_node.parent.left = None
        del_node.num = deep_left_node.num


root = node(None, None)
read_count = 0
while True:
    read_count += 1
    order = raw_input()
    splited_order = order.split(" ")
    if splited_order[0] == "insert":
        root.num = int(splited_order[1])
        break

for i in range(n_order - read_count):
    order = raw_input()
    splited_order = order.split(" ")
    if splited_order[0] == "insert":
        insert(int(splited_order[1]), root)
    elif splited_order[0] == "find":
        find(int(splited_order[1]), root)
    elif splited_order[0] == "delete":
        delete(int(splited_order[1]), root)
    elif splited_order[0] == "print":
        sys.stdout.write(" ")
        p_print(root)
        print ""
        sys.stdout.write(" ")
        c_print(root)
        print ""