Non-recursive add function in a binary tree using c++ - c++

I am writing an Add function to add nodes to a binary tree non recursively.
I have run into the problem of only being able to produce one level deep binary tree. I debugged it and I know where the problem is but can't figure out how to fix it. Maybe fresh pair of eyes will see something i dont...
The problem is that my temp node is being reset to the root value every new function call and hence, adding nodes linearly.
Anyways, here is the function:
void BinaryTreeNonRec::add(int num){
treeNode *temp, *parent;
if (root==NULL) {
root = new treeNode;
root->data=num;
root->left=0;
root->right=0;
temp=root;
printf("value is root \n");
} else {
temp=root;
while (temp!=NULL) {
if (num <= temp->data){
parent = temp;
temp=temp->left;
//root =temp;
printf("value is to the left \n");
} else {
parent =temp;
temp=temp->right;
//root=temp;
printf("value is to the right \n");
}
}
parent = new treeNode;
parent->data=num;
parent->left=NULL;
parent->right=NULL;
temp=parent;
}
}
Thanks for any kind of help.

You are not adding the new node to the tree, just running down the tree and filling parent with a new node, but never adding it to the tree, change below code:
parent = new treeNode;
parent->data=num;
parent->left=NULL;
parent->right=NULL;
temp=parent;
To:
treeNode *newNode = new treeNode;
newNode->data = num;
newNode->left = NULL;
newNode->right = NULL;
//Now insert the new node BELOW parent
if(num <= parent->data)
parent->left = newNode;
else
parent->right = newNode;

The problem might be that you never add your new node to the tree.
parent = new treeNode;
parent->data=num;
parent->left=NULL;
parent->right=NULL;
temp=parent;
You assign your new node to temp and parent, which are temporary variables and therefore don't exist outside of the function. What you have to do is assign your new node to either parent->left or parent->right, depending on which side your new input lies, in order to link it into the the tree. Therefore what you want to do is something like the following:
temp = new treeNode;
temp->data=num;
temp->left=NULL;
temp->right=NULL;
if(num < parent->data)
parent->left = temp;
else
parent->right = temp;

Algo
if root == null Create new node assign to Root
Keep iterating based on comparison with rootNode until reach any leaf Node
check if num <= parent(leaf) Insert into left ELSE insert into right
Code
private void insertItrInBST(int num){
Node temp = root,parent = root;
if(root == null){
root = getNewNode(num);
}else{
temp = root;
while(temp != null){
if(num <= root.data){
parent = temp;
temp = temp.left;
}else{
parent = temp;
temp = temp.right;
}
}
Node newNode = getNewNode(num);
if(num <= parent.data){
parent.left = newNode;
}else{
parent.right = newNode;
}
}
}

Related

How can I change this insert function to work in a linked list using strings?

This is the first question that I'm posting on StackOverflow, so forgive me if it seems kinda choppy.
For my computer science class, we're working with a double linked list for the current assignment. One of the functions required is an insert function.
I actually found an insert function on StackOverflow earlier this week, but it was set up to use structures inside of the main file instead of separate class files like this project is using. I think the function can work, but I'm not sure what alterations I need to make so that it can work with class files instead.
LinkedList.h member data
private:
Node *head, *tail;
mutable Node *it;
int count;
Insert function
bool LinkedList::insert(const string & str) const
{
LinkedList * tempVar;
if (hasMore) {
resetIterator();
}
else {
Node * temp = new Node;
//temp = str;
temp->data = str;
temp->next = it;
temp->prev = nullptr;
it->prev = temp;
it = temp;
}
if (it != nullptr) {
Node * current = it;
Node * previous = nullptr;
Node * tempNode = nullptr;
while (current->next != nullptr) {
tempNode = current->next;
if (current->data > tempNode->data) {
swap(current->data, tempNode->data);
}
else {
previous = current;
current = current->next;
}
}
tempVar->count += 1;
}
return false;
}
I haven't been able to test it yet due to not knowing what alterations are needed, but the function should insert strings that are passed into the argument into the linked list, as well as sort them in a dictionary style. Right now the only error is that temp = str; not working, and I'm not entirely sure what I need to do to get it to work.
Try something more like this:
bool LinkedList::insert(const string & str)
{
Node * current = head;
while ((current) && (current->data < str))
current = current->next;
Node *newNode = new Node;
newNode->data = str;
newNode->next = nullptr;
newNode->prev = nullptr;
if (current)
{
if (current->previous)
{
current->previous->next = newNode;
newNode->previous = current->previous;
}
current->previous = newNode;
newNode->next = current;
if (current == head)
head = newNode;
}
else
{
if (!head)
head = newNode;
if (tail)
{
tail->next = newNode;
newNode->previous = tail;
}
tail = newNode;
}
count += 1;
return true;
}
That being said, you really should be using the standard std::list container instead of implementing a double-linked list manually.

C++ trouble deleting nodes with only one child in BST

I'm having difficulty deleting a node in my binary search tree. The delete function is part of my Node class, and my findMin function is as well. Below is my delete function...
/**********************************************
* Delete
**********************************************/
node* node::Delete(node *root, string stuff)
{
//node *temp;
if (root == NULL) // Searches for value in tree
return NULL;
if (stuff < root->val) // String is in left subtree
root->left = Delete(root->left, stuff);
else if (stuff > root->val) // String is in right subtree
root->right = Delete(root->right, stuff);
else
{ // No children
if ((root->left == NULL) && (root->right == NULL))
{
delete(root);
root = NULL;
}
else if ((root->right == NULL) && (root->left != NULL)) // One left child node
{
node *temp = root;
root = root->left;
delete temp;
temp = NULL;
}
else if ((root->left == NULL) && (root->right!= NULL)) // One right child node
{
node *temp = root;
root = root->right;
delete temp;
temp = NULL;
}
else // Two children
{
node *temp = findMin(root->right); // Finds smallest value in right subtree
root->val = temp->val;
root->right = Delete(root->right, temp->val);
}
}
return root;
}
Below is my Destructor, which is giving me a SIGABRT (I'm using Xcode)
/**********************************************
* Destructor
**********************************************/
node::~node()
{
if (left != NULL) delete left;
if (right != NULL) delete right;
}
What my code is actually doing is not only deleting the node I intend to delete, but its child node. What could I be doing wrong? Is it an error with memory allocation? Is it an error with how I set the value to the child node?
You need to null your pointers to left and right before deleting a node.
You call:
node *temp = root;
root = root->left;
delete temp;
temp = NULL;
When you "delete temp" you are deleting a node which still points to root->left and root->right and your destructor insures they are also removed. You should instead do something like this:
node *temp = root;
root = root->left;
temp->left = NULL;
temp->right = NULL;
delete temp;
temp = NULL;
Also in your destructor you don't need to check if they are equal to null since delete already preforms this check.

Deleting the root node of a BST

I'm trying to make a remove function (without the use of recursion), that passes in the value of the node I want to remove.
My current problem is that my destructor seems to be making the program crash (getting a runtime error), which is probably because I'm not deleting the root node properly in my remove function.
The code I'm trying to use to remove the root is here:
bool BST::remove_root (int val)
{
if (val == root_->val)
{
if (root_->left == NULL && root_->right != NULL)
{
Node* temp = root_->right;
delete root_;
root_ = NULL;
size_--;
root_ = temp;
return true;
}
else if (root_->right == NULL && root_->left != NULL)
{
Node* temp = root_->left;
delete root_;
root_ = NULL;
size_--;
root_ = temp;
return true;
}
else
{
Node *curr = root_->right, *child = root_->left;
delete root_;
root_ = NULL;
size_--;
root_ = curr;
Node* temp = curr;
while (temp->left != NULL)
temp = temp->left;
temp->left = child;
return true;
}
}
}
In my code, just using val by itself is the value being passed in to the remove function (the one I want to remove). When I dereference things like root_->val, I'm accessing the val in my BST class.
I don't really understand why this wouldn't be able to continuously delete the root node (like I said I think it's the destructor making the program crash), but I feel like it could be invalid pointers?

Binary Search Tree Forgetting Every Node I Add

My problem is seemingly simple, but I can't find its solution. I have a binary tree, and this is my add function:
void collection::addToTree(vendor *& item)
{
Node * curr = root;
while (curr)
{
if (strcmp(item->getName(), root->item->getName()) < 0)
curr = curr->left;
else
curr = curr->right;
}
curr = new Node(item);
}
And this is my Node constructor:
collection::Node::Node(vendor *& item) : left(nullptr), right(nullptr)
{
this->item = item;
}
However, the tree is always empty, no matter what or how many items I try to add to it. The only other piece of code I can think of that will help you guys is my struct for my tree:
struct Node
{
Node();
Node(vendor *& item);
vendor * item;
Node *left, *right;
};
Node * root;
All of the sub-variables of vendor do have values (as I've seen in my debugger). I wish I could give you guys more detail, but this is all I know about the error. Any feedback is greatly appreciated.
In the add function, you're making only curr point to the new item, but that does not change back the previous left/right pointers, which probably is what you were aiming at.
You need to modify the left/right pointers directly, something like this:
void collection::addToTree(vendor *& item)
{
Node * curr = root;
while (curr)
{
if (strcmp(item->getName(), curr->item->getName()) < 0)
{
if (!curr->left)
{
curr->left = new Node(item);
return;
}
curr = curr->left;
}
else
{
if (!curr->right)
{
curr->right = new Node(item);
return;
}
curr = curr->right;
}
}
root = new Node(item);
}
Also, make sure you do Node * root = nullptr, as no initializing it can lead to it containing any arbitrary value.
Notice that I also changed if (strcmp(item->getName(), root->item->getName()) < 0) to if (strcmp(item->getName(), curr->item->getName()) < 0), as the branching is dependent on curr, not root.
I think the problem here is that your curr variable should be declared as Node **curr and receive the root's address in order for the change to be visible outside of the addToTree function.
void collection::addToTree(vendor *& item)
{
Node ** curr = &root;
while (*curr)
{
if (strcmp(item->getName(), (*curr)->item->getName()) < 0)
(*curr) = (*curr)->left;
else
(*curr) = (*curr)->right;
}
*curr = new Node(item);
}

adding a node in Multi Level Doubly link list in c

I am creating a multilevel doubly link list, I am performing the adding nodes operation in it. I'm confused because according to my logic code mentioned below it should print the value, but it is not printing. The output is not wrong but maybe I'm doing something wrong which could affect while flatten that list.
I have 3 levels of this list. addNode function will add at the very first level, where as addChild function will add a node anywhere in 2nd or 3rd level.
code is:
Student* StudentList::addNode(int num)
{
Student* node = new Student(num);
if(head == 0) {
head = node;
tail = node;
} else {
node->prev = tail;
tail->next = node;
tail = tail->next;
}
return node;
}
add child:
Student* StudentList::addChild(Student* node1, int num)
{
Student* node = head;
Student* temp;
Student* temp1;
// traversing the list to find exact location
while(node != 0)
{
if(node->num == node1->num) {
break;
} else {
temp = node->child;
while(temp)
{
if(temp->num == node1->num) {
node = temp;
break;
} else {
temp1 = temp->child;
while(temp1)
{
if(temp1->num == node1->num) {
node = temp1;
break;
} else {
temp1 = temp1->next;
}
}
temp = temp->next;
}
}
node = node->next;
}
}
Student* newChild = new Student(num);
Student* curr = node->child;
if(curr == 0)
{
node->child = newChild;
} else {
while(curr->next)
{
curr = curr->next;
}
newChild->prev = curr;
curr->next = newChild;
}
return node1;
}
Main Method code is:
StudentList* sl = new StudentList();
Student* newNode;
Student* newNode1;
newNode = sl->addNode(1);
newNode1 = sl->addChild(newNode,11);
sl->addChild(newNode1, 111);
sl->addChild(newNode1, 112);
newNode1 = sl->addChild(newNode,12);
newNode = sl->addNode(2);
newNode1 = sl->addChild(newNode,21);
newNode1 = sl->addChild(newNode,22);
sl->addChild(newNode1, 221);
sl->addChild(newNode1, 222);
sl->addChild(newNode1, 223);
newNode = sl->addNode(3);
newNode = sl->addNode(4);
newNode1 = sl->addChild(newNode,41);
sl->addChild(newNode1, 411);
sl->printList();
and my print list code is:
void StudentList::printList(){
Student* curr = head;
while(curr){
cout<< *curr <<endl;
if(curr->child){
Student* newCurr = curr->child;
while(newCurr){
cout<< "*{"<<newCurr->num <<"}"<<endl;
if(newCurr->child){
Student* newCurr2 = newCurr->child;
while(newCurr2){
//according to my login this 3rd level childs num(id) value
//should be printed used only for 2nd level according to my
//logic.. where is the problem am i doing wrong any thing?
cout<< "**{"<<newCurr2->num <<"}"<<endl;
newCurr2 = newCurr2->next;
}
}
newCurr = newCurr->next;
}
}
curr = curr->next;
}
}
Kindly help me in this, thanks in advance for everyone.
From the output you've put in your comment it looks like nothing is being added at the second level. Where you're expecting nodes to be added at the second level, they are being added to the first.
I think the problem is at the bottom of the add child function:
Student* StudentList::addChild(Student* node1, int num)
{
// rest of function. node1 is never modified
return node1;
}
You are always returning the node input to that function. I think in your following code
newNode = sl->addNode(1);
newNode1 = sl->addChild(newNode,11);
sl->addChild(newNode1, 111);
sl->addChild(newNode1, 112);
That you will find that newNode1 == nodeNode and not the child node as I think you are expecting. Probably the add child function should be returning newChild