Search code examples
c++pointersbinary-search-treesmart-pointersunique-ptr

Binary Search Tree using std::unique ptr


I'm trying to implement a Binary Search Tree using smart pointers and I've read that the recommended way to implement it is by using unique_ptr since a parent owns the child and there are no multiple owners in a binary search tree.

Take this tree for example,

                       10
            4                      20       
      2           5          11          30
         3

here 4 is left child of 10 and 2 is left child of 4 and 3 is right child of 2 and so on.

Now the struct looks like,

template<typename T>
struct TreeNode {
    T data;
    std::unique_ptr<TreeNode<T>> left, right; 
};

there's a unique_ptr<TreeNode<T>> root pointing to the root.

Now if I'm understanding it correctly unique_ptr's can't be copied or assigned and they have unique ownership of the object.

So if I want to traverse the tree I can't do something like initialize a std::unique_ptr<TreeNode<T>> temp to the root and traverse every node from there since it'll throw an error once I try to set the root which is a unique_ptr to the temp.

So do I need to use a raw pointer of type TreeNode* to traverse the tree and perform operations? is it good or safe to do so? For all my operations on this tree then will I have to use raw pointers?

Another problem is with deleting a node. If I say want to delete node with the value 3. If I initialize a raw pointer of type TreeNode* temp and arrive at Treenode 3. Then if I call delete(temp) what will happen? A unique_ptr from TreeNode 2 is pointing at TreeNode 3. What will happen to this pointer?


Solution

  • Then if I call delete(temp) what will happen?

    The TreeNode will be destroyed. Note that delete doesn't need parentheses

    A unique_ptr from TreeNode 2 is pointing at TreeNode 3. What will happen to this pointer?

    The pointer becomes invalid, and it is undefined behaviour for the unique_ptr object to be destroyed, as it will attempt to delete an invalid pointer.

    So do I need to use a raw pointer of type TreeNode* to traverse the tree and perform operations? is it good or safe to do so? For all my operations on this tree then will I have to use raw pointers?

    You can have a reference (or pointer) to a std::unique_ptr, you don't need to copy it.

    Rather than delete a raw pointer, you can call the reset member function of the unique_ptr to free the pointed-to TreeNode