简体   繁体   中英

Deleting node in BST (python)

Trying to build a binary search tree in python and came across this weird bug. After deleting nodes using my delete_node function, deleted nodes are still being printed, but only ones that are being deleted properly are nodes that have two other nodes attached to it (these ones are supposed to be hardest to delete though) Here's the code:

class Node:
  def __init__(self, data):
    self.Left = self.Right = None
    self.T_data = data


# function that deletes nodes from the tree
  def delete_node(self, item):
    if self is None:
      return self
    elif item < self.T_data:
      self.Left.delete_node(item)
    elif item > self.T_data:
      self.Right.delete_node(item)
    else:
      # case when the node we want to delete has no leaves attached to it
      if self.Right is None and self.Left is None:
        self = None
      # cases when a node has either left or right leaf node
      elif self.Left is None:
        temp = self.Right
        self = None
        return temp
      elif self.Right is None:
        temp = self.Left
        self = None
        return temp
      else: #case when a node has two leaf nodes attached
        temp = self.Right.min_node()
        self.T_data = temp.T_data
        self.Right = self.Right.delete_node(temp.T_data)
    return self

As you can see the way nodes are deleted is using a recursion, so for double-branched nodes to get deleted, the single-branch node deletion should work properly, but it does not.

heres the print function and how the functions are called:

# function that prints contents of the tree in preorder fashion
  def print_tree_preorder(self):
    if self is None:
      return
    print("%s" % self.T_data)
    if self.Left is not None:
      self.Left.print_tree_preorder()
    if self.Right is not None:
      self.Right.print_tree_preorder()

x = int(input("Which element would you like to delete?\n"))
  root = root.delete_node(x)
  root.print_tree_preorder()

What you're doing right now, when you have:

self = None

Is not actually deleting the object itself. What you're doing is assigning self to a different value.

I think a good way to illustrate this problem is thinking of self and other variables as a tag .

When you say:

a = 3

You are essentially having the tag a put on the entity 3. 3 resides somewhere in memory, and a "points" to 3(although pointers in C++ isn't really the references in python, so be careful if you're going to make that comparison).

When you point self to None , what you wanted to say was:

So I want to remove this object, and all things that point to this object will point to None instead.

However, what you're currently saying is:

So I want to set my self tag to point to None .

Which is completely different. Just because you set your self tag to None does not mean you set the node's parents .Right or .Left members to None as well.

The solution? Well, you're not gonna like this, but you're gonna have to either:

  1. have a pointer to the parent for each node, and set the parent's child(this child specifically) to None .

  2. check 1 levels deeper in your tree, so you can delete the child node instead of deleting the node itself.

The reason the case for 2 node children works is because you're setting the attribute of the object here, instead of setting self=None . What this means is that you're still pointing to the same object here, specifically on this line:

self.T_data = temp.T_data

It's the difference between "Coloring a object does not make it a different object. Its traits are just different" vs. "replacing a object with another object makes it a different object" .

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