Reputation: 2528
I have a binary search tree implementation where each node of the tree has this structure.
struct node {
T data;
std::unique_ptr<node> left, right;
node(T data): data(data), left(nullptr), right(nullptr) {}
};
I have implemented a findmin
routine that returns the minimum data(left most node's data), given the root of the tree. At present, I have implemented it recursively.
template<typename T>
T Btree<T>::_findmin(std::unique_ptr<node>& curr)
{
if (curr && curr->left == nullptr)
return curr->data;
return _findmin(curr->left);
}
This works but I would like to implement it iteratively. For a normal pointer, we can assign and then keep traversing the leftmost node curr = curr->left
, but such an assignment won't work for unique_ptr.
Is there a way to implement it iteratively?
Upvotes: 1
Views: 996
Reputation: 85767
The problem with your current function is that it takes a reference. We can't directly transform it to a loop because you can't reseat a reference (= make it point somewhere else).
However, we can do it with a pointer! We just have to add *
every time we use it.
template<typename T>
T Btree<T>::_findmin(std::unique_ptr<node> &root)
{
std::unique_ptr<node> *curr = &root;
while (true) {
if (*curr && (*curr)->left == nullptr)
return (*curr)->data;
curr = &(*curr)->left;
}
}
And there you have it: An iterative version of your function, bugs and all.
We can get rid of one level of indirection by taking advantage of one of unique_ptr's methods, get()
:
template<typename T>
T Btree<T>::_findmin(std::unique_ptr<node> &root)
{
node *curr = root.get();
while (true) {
if (curr && curr->left == nullptr)
return curr->data;
curr = curr->left.get();
}
}
Instead of operating on top of the smart pointer wrappers, we simply get the contents and use the raw underlying pointers.
Upvotes: 6