aajjbb
aajjbb

Reputation: 91

Change pointer to pointer to reference to pointer

I have a method to insert a node into a binary tree, which uses a pointer to pointer to correctly allocate new nodes in the tree.

As I'm using C++, I think that it's possible to change this pointer to pointer to a reference to pointer, leading to cleaner and C++-ish code. But how to do this and keep the allocation correct?

bool insert(T value) {
    node** buff = &root;

    while ((*buff) != NULL) {
        if (value == (*buff)->value) {
            return false;
        } else if (value < (*buff)->value) {
            buff = &(*buff)->left;
        } else {
            buff = &(*buff)->right;
        }
    }

    *buff = new node(value);
    return true;
}

Upvotes: 1

Views: 168

Answers (2)

bolov
bolov

Reputation: 75668

not tested, but this is the idea: you insert when you are in parent, not when you descended into null:

bool insert(T value) {
    if (root == nullptr) {
       root = new node(value);
       return true;
    }

    node* buff = root;    
    while(buff->value != value) {        
        if (value < buff->value) {
            if(buff->left == nullptr {
               buff->left = new node(value);
               return true;
            }
            buff = buff->left;
        } else {
            if (buff->right == nullptr) {
               buff->right = new node(value);
               return true;
            }
            buff = buff->right;
        }
    }

    return false;
}

how i would write it:

// returns the node under which the insertion must be done
// or nullptr if the value already exists in the tree
// prereq: tree must be not empty
node* findParentInsertionPoint(T value) {
    if (root == nullptr) {
       throw std::logic_erro("");
    }

    node* n = root;    
    while(n->value != value) {        
        if (value < n->value) {
            if(n->left == nullptr {
               return buff;
            }
            n= n->left;
        } else {
            if (n->right == nullptr) {
               return n;
            }
            n= n->right;
        }
    }
    return nullptr;
}

// inserts a leaf as child of parent
// prereq: parent must be not null
// the corresponding child must be null;
void insertLeafAt(T value, node * parent) {
   if (parent == nullptr) {
      throw std::logic_error("");
   }
   if (value < parent->value) {
      parent->left = new node(value);
   } else {
     parent->right = new node(value);
   }
}

bool insert(T value) {
    if (root == nullptr) {
       root = new node(value);
       return true;
    }

    node* parent = findParentInsertionPoint(value);
    if (parent == nulptr) {
       return false;
    }
    insertLeafAt(T value, parent);
    return true;
}

Upvotes: 2

Jarod42
Jarod42

Reputation: 217065

You cannot reassign a reference, so due to buff = &(*buff)->left;,
you can't change node** buff = &root; to node*& buff = root; (and replacing (*buff) by buff).

Upvotes: 0

Related Questions