What's wrong with this code for BST insertion? - c++

So I wrote this code for Insertion of a node in BST (Binary Search Trees) but the program always prints that the tree is empty. I guess there's a problem with the function call I've made. Can you explain the problem.
#include <bits/stdc++.h>
#include <conio.h>
using namespace std;
struct node
{
int key;
node* left;
node* right;
};
void insert(node* root, int item)
{
if(root == NULL)
{
node* temp = new node();
temp->key = item;
temp->left = NULL;
temp->right = NULL;
root = temp;
}
else
{
if((root->key)>item)
{
insert(root->left,item);
}
else
{
insert(root->right,item);
}
}
}
void inorder(node* root)
{
if(root!=NULL)
{
inorder(root->left);
cout<<" "<<root->key<<" ";
inorder(root->right);
}
else cout<<"The tree is empty.";
}
int main()
{
// cout<<endl<<" Here 5 ";
node* root = NULL;
int flag = 1 , item;
while(flag == 1)
{
cout<<"Enter the number you want to enter : ";
cin>>item;
// cout<<endl<<" Here 6";
insert(root, item);
cout<<"Do you want to enter another number (1 -> YES)?";
cin>>flag;
}
cout<<"The final tree is :";
inorder(root);
getch();
return 0;
}

First, the insertion is slightly incorrect. The root pointer must be passed by reference. Just some such as:
void insert(node *& root, int item)
{
if(root == NULL)
{
node* temp = new node();
temp->key = item;
temp->left = NULL;
temp->right = NULL;
root = temp;
}
else
{
if ((root->key) > item)
{
insert(root->left,item);
}
else
{
insert(root->right,item);
}
}
}
which is structurally identic to your code (except for the reference to the root)
Also, your inorder traversal is bizarre because it will print out the message "The tree is empty." each time that the traversal detects a null node. I would modify thus:
void inorder(node* root)
{
if (root == NULL)
return;
inorder(root->left);
cout<<" "<<root->key<<" ";
inorder(root->right);
}
Finally, I would slightly modify main() for managing the case when the tree is empty (instead of doing it inside inorder traversal):
int main()
{
node* root = NULL;
int flag = 1 , item;
while(flag == 1)
{
cout<<"Enter the number you want to enter : ";
cin>>item;
insert(root, item);
cout<<"Do you want to enter another number (1 -> YES)?";
cin>>flag;
}
cout<<"The final tree is :";
if (root == NULL)
cout << "The tree is empty.";
else
inorder(root);
cout << endl;
return 0;
}

Related

I'm trying to implement a binary tree. My program stops abruptly after a few node insertions. What is going wrong?

I'm just trying out implementation of binary tree. It's not for a college class so I cannot ask a teacher :(
I have tried debugging it with the Codeblocks debugger but I'm still not understanding what is going wrong.
I am using class instead of struct. Currently I have only implemented insertion and inorder traversal functions.
For insertion function, I am checking if the root node is NULL or not. If it is NULL, the newNode becomes equal to the root node. Or else, I find the appropriate parent node and then append the newNode as its child.
And, in the inorder traversal function, is my recursion correct?
Edit: Turns out that I wasn't initializing my Node variables. My code is working after initializing those variables. Thanks for your help!
#include<iostream>
using namespace std;
class Node
{
public:
int data;
Node* left_child;
Node* right_child;
};
Node* root = NULL;
void insertion();
void inorder_travesal(Node*);
int main(){
char ch;
do{
int choice;
cout<<"\nEnter your choice: \n1. Insertion\n2. Inorder Traversal\n : ";
cin>>choice;
switch(choice){
case 1: insertion();
break;
case 2: inorder_travesal(root);
break;
}
cout<<"\nDo you want to continue?: ";
cin>>ch;
}while(ch == 'y');
return 0;
}
void insertion(){
int data;
cout<<"\nEnter data: ";
cin>>data;
Node* newNode = new Node;
newNode->data = data;
if(root == NULL)
{
root = newNode;
return;
}
else
{
Node* temp = root;
while(true){
if(temp->data > newNode->data)
{
if(temp->left_child == NULL)
{
temp->left_child = newNode;
return;
}
else
{
temp = temp->left_child;
}
}
else
{
if(temp->right_child == NULL)
{
temp->right_child = newNode;
return;
}
else
{
temp = temp->right_child;
}
}
}
}
inorder_travesal(root);
}
void inorder_travesal(Node* temp){
if(temp->left_child != NULL){
inorder_travesal(temp->left_child);
}
cout<<temp->data<<" ";
if(temp->right_child != NULL){
inorder_travesal(temp->right_child);
}
}

Binary Search Tree implementation giving segmentation fault

This is the c++ code to implement binary search tree where program gets seg. fault:
#include<iostream>
#include<cstdlib>
#include<stack>
struct BSTNode
{
int info;
struct BSTNode *left, *right;
};
class BST
{
private:
//BSTNode *root;
public:
void rpreorder(BSTNode*);
void rinorder(BSTNode*);
void rpostorder(BSTNode*);
BSTNode * search(BSTNode*, int);
BSTNode* insert(BSTNode*, int);
};
void BST:: rpreorder(BSTNode *root)
{
if(root == NULL)
return ;
std::cout<<" "<<root->info;
rpreorder(root->left);
rpreorder(root->right);
}
void BST:: rinorder(BSTNode *root)
{
if(root = NULL)
return ;
rinorder(root->left);
std::cout<<" "<<root->info;
rinorder(root->right);
}
void BST:: rpostorder(BSTNode *root)
{
if(root == NULL)
return ;
rpostorder(root->left);
rpostorder(root->right);
std::cout<<" "<<root->info;
}
BSTNode * BST:: search(BSTNode* root, int data)
{
if(root == NULL)
return root;
if(data < root->info)
return search(root->left, data);
else if(data > root->info)
return search(root->right, data);
return root;
}
BSTNode* BST:: insert(BSTNode *root, int data)
{
BSTNode* parent;
BSTNode* newNode = new BSTNode;
newNode->info = data;
newNode->right = NULL;
newNode->left = NULL;
if(root == NULL)
root = newNode;
else
{
parent = root;
while(parent != NULL)
{
if(data < parent->info)
{
if(parent->left == NULL)
parent->left = newNode;
parent = parent->left;
}
else if(data > parent->info)
{
if(parent->right == NULL)
parent->right = newNode;
parent = parent->right;
}
}
}
return root;
}
int main()
{
int choice, value;
BST obj;
BSTNode *root = NULL;
while(1)
{
std::cout<<"\n Enter the choice : \n 1. To insert \n 2. To search \n 3. recursive preorder \n 4. recursive inorder \n 5. recursive \
postorder \n 6. EXIT \n : ";
std::cin>>choice;
switch(choice)
{
case 1:
std::cout<<"\n Enter element to insert : ";
std::cin>>value;
root = obj.insert(root, value);
break;
case 2:
std::cout<<"\n Enter the element to search : ";
std::cin>>value;
{
BSTNode* temp;
temp = obj.search(root, value);
if(temp == NULL)
std::cout<<"\n Element not found "<<std::endl;
else
std::cout<<"\n The element found ";
}
break;
case 3:
obj.rpreorder(root);
break;
case 4:
obj.rinorder(root);
break;
case 5:
obj.rpostorder(root);
break;
case 6:
exit(0);
}
}
return 0;
}
The seg. fault is coming in this segment of above code :
void BST:: rinorder(BSTNode *root)
{
if(root = NULL)
return ;
rinorder(root->left); // <- this line gives seg. fault
std::cout<<" "<<root->info;
rinorder(root->right);
}
There is one more problem to this code :
After inserting only one element in BST I can't insert more elements into the BST.

I would like not to use root as global

Hello I am writing an avl tree and I have one issue . I am currently having a root as global since I use it in the class as well as in main , how can I write it without having it global?
struct avl_node {
int data;
struct avl_node *left;
struct avl_node *right;
}*root;
class avlTree {
public:
int height(avl_node *temp)
{
int h = 0;
if (temp != NULL)
{
int l_height = height (temp->left);
int r_height = height (temp->right);
int max_height = max (l_height, r_height);
h = max_height + 1;
}
return h;
}
int diff(avl_node *temp)
{
int l_height = height (temp->left);
int r_height = height (temp->right);
int b_factor= l_height - r_height;
return b_factor;
}
avl_node *rr_rotation(avl_node *parent)
{
avl_node *temp;
temp = parent->right;
parent->right = temp->left;
temp->left = parent;
return temp;
}
avl_node *ll_rotation(avl_node *parent)
{
avl_node *temp;
temp = parent->left;
parent->left = temp->right;
temp->right = parent;
return temp;
}
avl_node *lr_rotation(avl_node *parent)
{
avl_node *temp;
temp = parent->left;
parent->left = rr_rotation (temp);
return ll_rotation (parent);
}
avl_node *rl_rotation(avl_node *parent)
{
avl_node *temp;
temp = parent->right;
parent->right = ll_rotation (temp);
return rr_rotation (parent);
}
avl_node* balance(avl_node *temp)
{
int bal_factor = diff (temp);
if (bal_factor > 1)
{
if (diff (temp->left) > 0)
temp = ll_rotation (temp);
else
temp = lr_rotation (temp);
}
else if (bal_factor < -1)
{
if (diff (temp->right) > 0)
temp = rl_rotation (temp);
else
temp = rr_rotation (temp);
}
return temp;
}
avl_node* insert(avl_node *root, int value)
{
if (root == NULL)
{
root = new avl_node;
root->data = value;
root->left = NULL;
root->right = NULL;
return root;
}
else if (value < root->data)
{
root->left = insert(root->left, value);
root = balance (root);
}
else if (value >= root->data)
{
root->right = insert(root->right, value);
root = balance (root);
}
return root;
}
void display(avl_node *ptr, int level)
{
int i;
if (ptr!=NULL)
{
display(ptr->right, level + 1);
printf("\n");
if (ptr == root)
cout<<"Root -> ";
for (i = 0; i < level && ptr != root; i++)
cout<<" ";
cout<<ptr->data;
display(ptr->left, level + 1);
}
}
void inorder(avl_node *tree)
{
if (tree == NULL)
return;
inorder (tree->left);
cout<<tree->data<<" ";
inorder (tree->right);
}
void preorder(avl_node *tree)
{
if (tree == NULL)
return;
cout<<tree->data<<" ";
preorder (tree->left);
preorder (tree->right);
}
void postorder(avl_node *tree)
{
if (tree == NULL)
return;
postorder ( tree ->left );
postorder ( tree ->right );
cout<<tree->data<<" ";
}
avlTree()
{
root = NULL;
}
};
int main()
{
int choice, item;
avlTree avl;
while (1)
{
cout<<"\n---------------------"<<endl;
cout<<"AVL Tree Implementation"<<endl;
cout<<"\n---------------------"<<endl;
cout<<"1.Insert Element into the tree"<<endl;
cout<<"2.Display Balanced AVL Tree"<<endl;
cout<<"3.InOrder traversal"<<endl;
cout<<"4.PreOrder traversal"<<endl;
cout<<"5.PostOrder traversal"<<endl;
cout<<"6.Exit"<<endl;
cout<<"Enter your Choice: ";
cin>>choice;
switch(choice)
{
case 1:
system("cls");
cout<<"Enter value to be inserted: ";
cin>>item;
root = avl.insert(root, item);
break;
case 2:
system("cls");
if (root == NULL)
{
cout<<"Tree is Empty"<<endl;
continue;
}
cout<<"Balanced AVL Tree:"<<endl;
avl.display(root, 1);
break;
case 3:
system("cls");
cout<<"Inorder Traversal:"<<endl;
avl.inorder(root);
cout<<endl;
break;
case 4:
system("cls");
cout<<"Preorder Traversal:"<<endl;
avl.preorder(root);
cout<<endl;
break;
case 5:
system("cls");
cout<<"Postorder Traversal:"<<endl;
avl.postorder(root);
cout<<endl;
break;
case 6:
exit(1);
break;
default:
system("cls");
cout<<"Wrong Choice"<<endl;
}
}
return 0;
}
You should not explicitly use the tree's root in main(), and generally outside the tree's methods. To achieve this just make the method
avl_node* insert(avl_node *where, int value)
private (or protected, at least) in a class and add a public interface:
void insert(int value)
{
root = insert(root, value);
}
Then in main you add items simply by calling
avlTree tree;
....
tree.insert(item);
EDIT to answer a question asked in a comment.
Functions like display, inorder etc. should be handled in the same way as insert: declare a public, parameterless function to launch the action and a protected method with a parameter to recursively perform it:
public:
void display() { display(root, 0); }
void inorder() { inorder(root); }
.....
protected:
void display(avl_node *node, int level)
{
if (node!=NULL)
{
display(node->right, level + 1);
if (node == root)
cout << "Root -> ";
else
cout << " ";
cout << setw(5*level) << "" << node->data << endl;
display(node->left, level + 1);
}
}
void inorder(avl_node *node)
{
if (node)
{
inorder (node->left);
cout << node->data << " ";
inorder (node->right);
}
}
then use:
tree.display();
tree.inorder();

How to make a string and an integer as paramaters in binary search tree?

I'm new to the programming world and I have been stuck in the same problem for couple days. My assignment is to create a binary search tree that takes a string and an integer as parameters and stores the pair in the tree. My code works fine for the string but not for integers, for example if I input "John" for the string and "2" for the integers, it will only output "John"! My whole code is below to give you guys an idea of what's going on.
BST.cpp:
#include"BST.h"
#include<string>
#include<fstream>
BST::BST()
{
this->root = NULL; //root is NULL in the start
}
BST::~BST()
{
clear(root); //delete all nodes
}
void BST::clear(Node* current)
{
if(current == NULL)
return;
clear(current->getLeft()); //clear left subtree
clear(current->getRight()); //clear right subtree
delete current; //delete this node
}
void BST::Insert(string num, int data)
{
//create new node to be inserted
Node *n = new Node();
n->setData(num, data);
n->setLeft(NULL);
n->setRight(NULL);
if(this->root == NULL) //if root is null, simply add at root
root = n;
else
InsertHelper(root,n); //call helper to insert
}
void BST::InsertHelper(Node* current, Node* newnode)
{
if(current == NULL)
return;
//node should be inserted at right subtree
if(current->getData() <= newnode->getData()){
//if no node at right
if(current->getRight() == NULL )
current->setRight(newnode); //add at right node
else
InsertHelper(current->getRight(), newnode); //insert in right subtree
}
else{
if(current->getLeft() == NULL){ //if no node at left
current->setLeft(newnode); //add at left
}else{
InsertHelper(current->getLeft(), newnode); //insert in left subtree
}
}
}
bool BST::find(string num)
{
return findHelper(root,num);
}
bool BST::findHelper(Node *current,string num)
{
if(current == NULL)
return false;
if(current->getData() == num) //if number is founf
return true;
if(num < current->getData()) //if number is less than current node
return findHelper(current->getLeft(),num); //go to left tree
else
return findHelper(current->getRight(),num); //go to right tree
}
void BST::min()
{
findMinHelper(root);
}
void BST::findMinHelper(Node* current)
{
if(current == NULL)
return;
if(current->getLeft() == NULL) //if no node at right
cout<<current->getData(); //current has min data
else
findMinHelper(current->getLeft()); //check on left subtree
}
void BST::max()
{
findMaxHelper(root);
}
void BST::findMaxHelper(Node * current)
{
if(current == NULL)
return;
if(current->getRight() == NULL) //if no node at right
cout<<current->getData(); //current node has max data
else
findMaxHelper(current->getRight()); //check on right subtree
}
void BST::LoadFromFile(string filename)
{
ifstream fin;
fin.open(filename.c_str()); //open input file
if(fin.fail())
cout<<"Unable to open input file";
else{
string x;
fin>>x;
while(!fin.eof()) //while file is not ended
{
// Insert(x); //insert in tree
fin >>x; //read next numbers
}
cout<<"Data successfully loaded!!"<<endl;
}
}
void BST::save_file(string filename)
{
ofstream fout;
fout.open(filename.c_str()); //open output file
saveHelper(fout,root); //call helper function
cout<<"Successfully saved\n\n";
}
void BST::saveHelper(ofstream &fout, Node* current)
{
if(current == NULL)
return;
saveHelper(fout,current->getLeft()); //save left tree
fout<<current->getData() << " "; //save current data
saveHelper(fout,current->getRight()); //save right tree
}
void BST::Print()
{
printHelper(root);
}
void BST::printHelper(Node *current)
{
if(current == NULL) //stop if NULL
return;
printHelper(current->getLeft()); //print left tree
cout<<current->getData() << " "; //print current node data
printHelper(current->getRight()); //print right tree
}
void BST::Delete(string num){
root = DeleteHelper(root,num);
}
Node* BST::DeleteHelper(Node *current, string num)
{
if(current == NULL)
return NULL;
Node *tobeReturned;
if (current->getData() == num) { //if key is found
if (current->getLeft() == NULL) { //no node at left
tobeReturned = current->getRight();
delete current;
return tobeReturned; //right subtree should replace this node
} else if (current->getRight() == NULL) {
tobeReturned = current->getLeft();
delete current;
return tobeReturned;
} else {
//find maximum node in the left subtree
Node * maxnode = findMaximum(current->getLeft());
//copy values from max node to this node
// current->setData(maxnode->getData());
//delete the max node
current->setLeft(DeleteHelper(current->getLeft(), num));
}
cout<<"Deleted!!!";
} else { //not found
if (num < current->getData()) {
current->setLeft(DeleteHelper(current->getLeft(),num));
} else {
current->setRight(DeleteHelper(current->getRight(), num));
}
}
return current;
}
Node* BST::findMaximum(Node * n)
{
if(n->getRight() == NULL) //if no node at right, current is maximum
return n;
return findMaximum(n->getRight()); //find in right subtree
}
BST.h:
#ifndef BST_H_
#define BST_H_
#include<iostream>
using namespace std;
#include<string>
#include "Node.h"
//BST class
class BST{
private:
Node * root; //root node pointer
public:
BST(); //constructor
~BST(); //destructor
void Insert(string num, int data); //Inserts new number in tree
bool find(string num); //finds whether a number is present in tree
void min(); //find and print minimum number in the tree
void max(); //find and print maximum number in the tree
void save_file(string filename); //save the tree to file
void Delete(string num); //deletes a number from tree
void LoadFromFile(string filename); //loads numbers from file to tree
void Print(); //print tree to stdout
//private functions used as helper functions in the public operations
private:
void printHelper(Node *root);
bool findHelper(Node *root,string num);
void InsertHelper(Node* current, Node* newnode);
void findMinHelper(Node* current);
void findMaxHelper(Node * current);
void saveHelper(ofstream &fout, Node* current);
Node* DeleteHelper(Node *current, string num);
Node * findMaximum(Node * n);
void clear(Node *currnt);
};
#endif
driver.cpp:
#include"BST.h"
#include<iostream>
using namespace std;
void print_menu()
{
cout<<"\n\nEnter 1 to Insert new number."<<endl;
cout<<"Enter 2 to Find number."<<endl;
cout<<"Enter 3 to Print."<<endl;
cout<<"Enter 4 to print min."<<endl;
cout<<"Enter 5 to print max."<<endl;
cout<<"Enter 6 to save to file."<<endl;
cout<<"Enter 7 to delete a number."<<endl;
cout<<"Enter 8 to load data from file."<<endl;
cout<<"Enter 9 to exit."<<endl;
cout<<"Enter your choice: ";
}
int main()
{
bool done = false;
int choice,data;
string fname, num;
BST tree;
while(!done)
{
print_menu();
cin >> choice;
switch(choice)
{
case 1:
cout<<"Enter key: ";
cin >> num;
cout<<"Enter data:";
cin >> data;
tree.Insert(num,data);
cout<<"Number add successfully"<<endl;
break;
case 2:
cout<<"Enter number: ";
cin >> num;
if(tree.find(num))
cout<<"Number exists!!"<<endl;
else
cout<<"Number not found"<<endl;
break;
case 3:
tree.Print();
break;
case 4:
tree.min();
break;
case 5:
tree.max();
break;
case 6:
cout<<"Enter filename:";
cin>>fname;
tree.save_file(fname);
break;
case 7:
cout<<"Enter number:";
cin>>num;
tree.Delete(num);
break;
case 8:
cout<<"Enter filename:";
cin>>fname;
tree.LoadFromFile(fname);
break;
case 9:
done = true;
break;
default:
cout<<"Invalid option selected..\n";
break;
}
}
return 0;
}
Node.cpp:
#include"Node.h"
#include<string>
Node::Node()
{
this->left = NULL;
this->right = NULL;
}
void Node::setData(string num, int data)
{
this->num = num;
}
string Node::getData()
{
return this->num;
}
void Node::setLeft(Node *l)
{
this->left = l;
}
Node* Node::getLeft()
{
return this->left;
}
void Node::setRight(Node *r)
{
this->right = r;
}
Node* Node::getRight()
{
return this->right;
}
Node.h:
#ifndef NODE_H_
#define NODE_H_
#include<iostream>
using namespace std;
class Node{
private:
int data; //number
Node *left; //left child
Node *right; //right child
std::string num;
public:
Node(); //constructor
void setData(string num, int data); //sets number in node
string getData(); //return numbers from node
void setLeft(Node *l); //sets left child pointer
Node* getLeft(); //returns left child pointer
void setRight(Node *r); //sets right child pointer
Node* getRight(); //return right child pointer
};
#endif
Does anyone see the problem on my code?
In node.cpp, you are not setting the integer value
void Node::setData(string num, int data)
{
this->num = num;
this->data = data; //missing line!
}
Also while printing, you need to modify a bit
cout<<current->getName() << " " << current->getNumber() << " " ;
Add these methods to your Node class : getName & getNumber which return string and integer of the class respectively. Use them instead of getData method

I'm having trouble with cpp code to insert elements in a binary tree

I've tried this way to insert elements in a binary tree in code blocks. The program got compiled but got a run time error and the program stopped running. Could some one please help me out in this issue.
Thanks in advance.
#include <iostream>
#include <cstdlib>
using namespace std;
class bst;
class node
{
public:
int data;
node *lc;
node *rc;
};
class bst
{
public:
node *root;
bst()
{
root = NULL;
}
void search(int, node **, node **);
void insert(int);
void display(node *, int);
};
void bst::search(int item, node **par, node **loc)
{
node *current;
node *ptr;
if(root == NULL)
{
*par = NULL;
*loc = NULL;
return;
}
if(item == root->data)
{
*par = NULL;
*loc = root;
return;
}
if(item < root->data)
current = root->lc;
else
current = root->rc;
ptr = root;
while(current != NULL)
{
if(item == current->data)
{
*par = ptr;
*loc = current;
return;
}
ptr = current;
if(item < current->data)
current = current->lc;
else
current = current->rc;
}
*par = current;
*loc = NULL;
}
void bst::insert(int item)
{
node *parent;
node *location;
node *temp;
search(item, &parent, &location);
temp = new node;
temp->data = item;
temp->lc = NULL;
temp->rc = NULL;
if(item < parent->data)
parent->lc = temp;
else
parent->rc = temp;
}
void bst::display(node *ptr, int level)
{
if(ptr != NULL)
{
display(ptr->rc, level+1);
cout<<"\n";
for(int i=0;i<level;i++)
cout<<" ";
cout<<ptr->data;
display(ptr->lc, level+1);
}
}
int main()
{
int ch, num;
bst b;
while(1)
{
cout<<"1. INSERT ; 2. DISPLAY ; 3. EXIT "<<endl;
cout<<"Enter your choice"<<endl;
cin>>ch;
switch(ch)
{
case 1: cout<<"Enter the number to insert"<<endl;
cin>>num;
b.insert(num);
break;
case 2: b.display(b.root, 1);
break;
case 3: exit(0);
}
}
return 0;
}
In this line search(item, &parent, &location); you are calling the function search with arguments of types int, node** and node**. It in fact expects int, node* and node*. You should change the function declaration to search(int, node**, node**).