简体   繁体   中英

Deleting a leaf node in Binary Search Tree

In Binary Search Tree (BST), I am trying to delete a leaf node by the following method. However, though 'id' is same, it is not getting deleted.

Code -

class BSTNode:
    def __init__(self, value):
        self.value=value
        self.left=None
        self.right=None


def insert(self, new_value):
    if new_value<self.value:
        if self.left:
            self.left.insert(new_value)
        else:
            self.left=BSTNode(new_value)
    else:
        if self.right:
            self.right.insert(new_value)
        else:
            self.right=BSTNode(new_value)

def inorder(self):
    if self.left:
        self.left.inorder()        
    
    print(self.value, end=' ')
    
    if self.right:
        self.right.inorder()

def delete(self, value_to_delete):
    print('\n')
    print('self.value', self.value)
    print('self.left', self.left, 'left id', id(self.left))
    print('self.right', self.right, 'right id', id(self.right))
    
    if value_to_delete==self.value:
        print('self.value', self.value, 'self ', self, 'self id', id(self) )
        self=None
    elif value_to_delete<self.value:
        self.left.delete(value_to_delete)
    else:
        self.right.delete(value_to_delete)

bsttree=BSTNode(10)
bsttree.insert(5)
bsttree.insert(15)
print('Inorder')
bsttree.inorder()
bsttree.delete(5)
print('Inorder after deletion of leaf node 5')
bsttree.inorder()

Code output

Inorder
5 10 15 

self.value 10
self.left <__main__.BSTNode object at 0x7febad1585b0> left id 140650197910960
self.right <__main__.BSTNode object at 0x7febad04e880> right id 140650196822144


self.value 5
self.left None left id 4529773304
self.right None right id 4529773304
self.value 5 self  <__main__.BSTNode object at 0x7febad1585b0> self id 140650197910960
Inorder after deletion of leaf node 5
5 10 15 

However, if I change the 'delete' function to below, the node gets deleted

def delete(self, value_to_delete):
    print('\n')
    print('self.value', self.value)
    print('self.left', self.left, 'left id', id(self.left))
    print('self.right', self.right, 'right id', id(self.right))
    
    if value_to_delete==self.value:
        print('self.value', self.value, 'self ', self, 'self id', id(self), )
        return None
    elif value_to_delete<self.value:
        self.left=self.left.delete(value_to_delete)
    else:
        self.right=self.right.delete(value_to_delete)

Do you know why it is deleting in the second case and not in the first?**

The first form of your delete is a no-operation. The self name inside it is just a local variable, and changing it to None will not affect any reference to it on the parent node.

The second form updates the reference on the parent node itself, with the returned value. It is also broken, because intermediate nodes also return None (it is an implicit return, since you don't write a return statement) - therefore, grand-parent nodes will delete the parent nodes, all the way down. The code, as is, will just work in a tree of height 2.

Something along this will fix most of the issues (although I am not checking for further corner cases):

def delete(self, value_to_delete):
    ...
    if value_to_delete==self.value:
        print('self.value', self.value, 'self ', self, 'self id', id(self), )
        return None
    elif value_to_delete<self.value:
        self.left=self.left.delete(value_to_delete)
    else:
        self.right=self.right.delete(value_to_delete)
    return self

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM