Destructor for Tree Node Class

Destructor Flaticon

Introduction

Creating a Destructor for tree node class is a common practice in programming when dealing with dynamically allocated memory. The destructor is responsible for cleaning up resources and memory associated with a class when an object is no longer in use. In the context of a tree node class, it plays a vital role in preventing memory leaks and maintaining efficient memory management.

In this guide, we will explore “Destructor” class for deleting a node from Binary tree.

The Role of a Destructor for Tree Node Class

A destructor is a special member function in a class that is automatically called when an object of the class goes out of scope or is explicitly deleted. Its primary purpose is to release any resources, such as dynamically allocated memory, that the class may have acquired during its lifetime.

For tree node classes, the destructor plays a crucial role in:

Deleting node using Destructor class Example

Consider a Binary Tree : Let us take an example.

Destructor Example

In the ‘BinaryTreeNode’ class, a destructor function is declared to handle the cleanup of a tree node. When the ‘delete’ keyword is applied to an object of this class, it initiates the removal of the entire binary tree, and the object’s destructor is invoked.

  • The ‘delete’ keyword is used on the children nodes, triggering their respective destructors one by one.
  • This process continues recursively until the entire binary tree is deleted.
  • Consider the tree above: when the destructor is called for the root node ’13’, it, in turn, invokes the destructors for 11′ and ’15’. Node ’11’ further calls the same process for its left and right children with data ‘9’ and ’12’.
  • Ultimately, the tree is deleted in a specific order: 9 -> 12 ->11 -> 15 -> 13 (following a post-order traversal).

Prime Course Trailer

Related Banners

Get PrepInsta Prime & get Access to all 200+ courses offered by PrepInsta in One Subscription

Implementation of Destructor for Tree Node Class

In Python, you don’t need to explicitly define destructors like you do in C++. Python has a garbage collector that automatically reclaims memory when objects are no longer referenced. However, if you want to perform cleanup or specific actions when an object is deleted, you can define a special method called “__del__”.

Code :

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

    def __del__(self):
        # Optionally, you can perform cleanup actions here
        print(f"Deleted node with data: {self.data}")

# Creating a binary tree
root = TreeNode(1)
root.left = TreeNode(2)
root.right = TreeNode(3)
root.left.left = TreeNode(4)
root.left.right = TreeNode(5)

# Deleting the root node will trigger the __del__ method, leading to a recursive "deletion" of the entire tree
del root

Output :

Deleted node with data: 4
Deleted node with data: 5
Deleted node with data: 2
Deleted node with data: 3
Deleted node with data: 1

Explanation :

In the provided Python code, a binary tree of “TreeNode” objects is created. The “__del__” method, defined within the class, is responsible for performing custom cleanup when an object is deleted. Upon deleting the root node, the “__del__” method is called recursively for all nodes in a post-order manner. As each node is deleted, a message indicating its data is printed, illustrating the orderly deletion of the tree’s nodes.

BST Destructor without Recursion

In Python, you can achieve a non-recursive destructor for a binary search tree (BST) using an iterative approach. Here’s an example of a BST destructor in Python without recursion:

Code :

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

def destroy_bst(root):
    if not root:
        return

    stack = []
    current = root

    while stack or current:
        if current:
            stack.append(current)
            current = current.left
        else:
            current = stack.pop()
            # Optionally, perform any cleanup or custom logic here
            print(f"Deleted node with data: {current.data}")
            # Explicitly remove the node to avoid re-visiting it
            current = None
            current = current.right

def main():
    # Creating a binary search tree
    root = TreeNode(3)
    root.left = TreeNode(1)
    root.right = TreeNode(5)
    root.left.right = TreeNode(2)
    root.right.left = TreeNode(4)

    # Deleting the entire BST using the non-recursive destructor
    destroy_bst(root)

if __name__ == "__main__":
    main()

Output :

Deleted node with data: 1
Deleted node with data: 2
Deleted node with data: 4
Deleted node with data: 5
Deleted node with data: 3

Explanation :

The Python code illustrates a non-recursive destructor for a binary search tree (BST). Using an iterative approach with a stack, it simulates an in-order traversal of the tree while deleting nodes. Messages are printed for each deleted node, showcasing the order of deletion. This approach allows for efficient destruction of the BST without the use of recursion, demonstrating a key principle in data structure management.

Usage and Best Practices

When working with tree node classes, here are some best practices for using destructors:

  • Ensure that a destructor is defined if your class acquires resources that need cleanup.
  • Implement the destructor to perform proper resource deallocation, such as releasing memory or closing handles.
  • If you have custom resources in your class, make sure they are properly cleaned up in the destructor.
  • Avoid manual memory leaks by employing the destructor to handle dynamically allocated memory.
  • Be cautious with circular references in the tree structure to prevent infinite recursion in the destructor.

To Wrap it up: 

In summary, creating a destructor for a tree node class is a crucial step in proper memory management and resource cleanup. It helps prevent memory leaks, ensures efficient memory usage, and contributes to the overall reliability and performance of software utilizing tree data structures.

Question 1.

What is a destructor in Python?

In Python, a destructor is defined using the “__del__” method, and it’s used for performing custom cleanup when an object is no longer in use.

Question 2.

How is the __del__ method different from constructors like __init__ in Python?

The “__init_” method is used for object initialization, while the “__del__” method is used for cleanup when an object is deleted. They serve different purposes in the object’s lifecycle.

Question 3.

Do I need to manually call the destructor in Python?

No, Python’s garbage collector automatically calls the “__del__” method when an object is no longer referenced and needs to be deleted. Manual calls to the destructor are not necessary.

Get over 200+ course One Subscription

Courses like AI/ML, Cloud Computing, Ethical Hacking, C, C++, Java, Python, DSA (All Languages), Competitive Coding (All Languages), TCS, Infosys, Wipro, Amazon, DBMS, SQL and others

Checkout list of all the video courses in PrepInsta Prime Subscription

Checkout list of all the video courses in PrepInsta Prime Subscription