I am trying to implement a Binary search tree with functionalities such as Deleting a node, finding the minimum node, maximum node, etc. But I am not able to Delete a node nor find Maximum or Minimum value in the tree. My take is that when I am inserting the nodes, the pointer to the node references to the last node hence my program cannot iterate from the root node. Any suggestion?
#include<iostream>
using namespace std;
struct BstNode
{
BstNode* left;
BstNode* right;
int data;
};
BstNode* GetnewNode(int data)
{
BstNode* newNode=new BstNode();
newNode->data=data;
newNode->left=NULL;
newNode->right=NULL;
return newNode;
}
BstNode* Insert(BstNode* root ,int data)
{
if(root==NULL)
{
root=GetnewNode(data);
}
else if(data<=root->data)
{
root=Insert(root->left,data);
}
else
{
root=Insert(root->right,data);
}
return root;
}
bool Search(BstNode* root, int data)
{
if(root==NULL)
{
return false;
}
else if(data==root->data)
{
return true;
}
else if(data<=root->data)
{
return Search(root->left,data);
}
else
{
return Search(root->right,data);
}
}
int FindMin(BstNode* root)
{
if(root==NULL)
{
return -1;
}
else
{
while(root->left!=NULL)
{
root=root->left;
}
}
return root->data;
}
bool IsBstUtil(BstNode* root, int minvalue, int maxvalue)
{
if(root==NULL)
return true;
if(root->data<minvalue && root->data >maxvalue && IsBstUtil(root->left,minvalue,root->data) && IsBstUtil(root->right,root->data,maxvalue))
{
return true;
}
else
{
return false;
}
}
bool IsBinarySearchTree(BstNode* root)
{
return IsBstUtil(root, INT_MIN, INT_MAX);
}
int FindMax(BstNode* root)
{
if(root==NULL)
{
return -1;
}
else
{
while(root->right!=NULL)
{
root=root->right;
}
}
return root->data;
}
BstNode* del(BstNode* root, int data)
{
if(root==NULL)
return root;
else if(data<=root->data)
root->left=del(root->left,data);
else if(data>root->data)
root->right=del(root->right,data);
else
{
if(root->left==NULL && root->right==NULL)
{
root=NULL;
delete root;
}
else if(root->left==NULL)
{
BstNode* temp=root;
root=root->right;
delete temp;
return root;
}
else if(root->right==NULL)
{
BstNode* temp=root;
root=root->left;
delete temp;
return root;
}
}
}
int main()
{
BstNode* root=NULL;
root=Insert(root,1);
root=Insert(root,3);
root=Insert(root,4);
}
Just instead of doing root = Insert(root->left,data); you should do set it as left to the root i.e
root->left = Insert(root->left,data);
Insert function:
BstNode* Insert(BstNode* root ,int data)
{
if(root==NULL)
{
root=GetnewNode(data);
}
else if(data<=root->data)
{
// setting the left to root
root->left=Insert(root->left,data);
}
else
{
// setting the right to root
root->right=Insert(root->right,data);
}
// returning the root itself
return root;
}
Related
#include <iostream>
using namespace std;
class BST {
int data;
BST *left, *right;
public:
BST();
BST(int);
BST* Insert(BST*, int);
void Delete(BST*, BST*, int);
void Inorder(BST*);
};
BST::BST():data(0), left(NULL), right(NULL) {}
BST::BST(int value):BST() {
data = value;
}
BST* BST::Insert(BST *root, int value) {
if(!root) {
return new BST(value);
}
if(value > root->data) {
root->right = Insert(root->right, value);
} else {
root->left = Insert(root->left, value);
}
return root;
}
void BST::Delete(BST *parent, BST *root, int value) {
if(!root) {
return;
}
if(root->data == value) {
if(!root->left && !root->right) {
if(parent) {
if (parent->left == root) {
parent->left = NULL;
}
else {
parent->right = NULL;
}
}
free(root);
return;
}
if(!root->left || !root->right) {
BST *child = root->left ? root->left : root->right;
if(parent) {
if (root == parent->left) {
parent->left = child;
}
else {
parent->right = child;
}
free(root);
} else {
// what do i have to do here ?
}
return;
}
BST *inorderSuccessor = root->right;
parent = root;
while (inorderSuccessor->left) {
parent = inorderSuccessor;
inorderSuccessor = inorderSuccessor->left;
}
root->data = inorderSuccessor->data;
Delete(parent, inorderSuccessor, inorderSuccessor->data);
}
if(value > root->data) {
Delete(root, root->right, value);
} else {
Delete(root, root->left, value);
}
}
void BST::Inorder(BST *root) {
if(!root) {
return;
}
Inorder(root->left);
cout << root->data << " ";
Inorder(root->right);
}
int main() {
BST bst, *root = NULL;
root = bst.Insert(root, 4);
bst.Insert(root, 2);
// bst.Insert(root, 5);
bst.Insert(root, 1);
bst.Insert(root, 3);
bst.Delete(NULL, root, 4);
bst.Inorder(root);
return 0;
}
When i do free(root) whole of tree gets deleted.
I have done almost everything I know but it just doesn't run correctly.
I am keeping track of parent node in the function itself.
I am using recursion to do that. I can tell a node is root of tree if parent is null.
Everything else is working fine. I have checked all the other cases.
I've an assignment which is to write an index builder application , which takes text consisting of lines and prints a list of the words of the text and the lines they appear on are printed next to them.
but i faced a problem when i tried to handle the case if the word already exist , it's always add a redundant number to the vector
can anyone help me please?
This is the definition of the BSTnode:
class BSTnode
{
public:
string data;
vector<int> linesAppear;
BSTnode* left;
BSTnode* right;
BSTnode()
{
left = right = NULL;
}
};
This is the definition of the BSTFCI:
class BSTFCI
{
public:
BSTnode* root;
BSTFCI()
{
root = NULL;
}
void add(string ToBST,int lineAppear);
BSTnode* Insert(BSTnode*& node,string ToBST,int lineAppear);
BSTnode* create_new_node(string ToBST,int lineAppear);
};
The functions for insert
BSTnode* BSTFCI::create_new_node(string ToBST,int lineAppear)
{
BSTnode* Temp = new BSTnode();
Temp->data = ToBST;
Temp->left = Temp->right = NULL;
Temp->linesAppear.push_back(lineAppear);
return Temp;
}
BSTnode* BSTFCI::Insert(BSTnode*& node,string ToBST,int lineAppear)
{
if(node == NULL)
{
node = create_new_node(ToBST,lineAppear);
}
if(ToBST > node->data)
{
node->right = Insert(node->right,ToBST,lineAppear);
}
if(ToBST < node->data)
{
node->left = Insert(node->left,ToBST,lineAppear);
}
//cout <<"inside insert"<< ToBST << endl;
if(node->data == ToBST)
{
node->linesAppear.push_back(lineAppear);
// cout <<"inside insert condition "<< node->data << endl;
}
return node;
}
void BSTFCI::add(string ToBST,int lineAppear)
{
root = Insert(root,ToBST,lineAppear);
}
the main function:
int main()
{
BSTFCI o;
string input,ToBST;
int lineAppear = 0;
while(getline(cin,input))
{
if(input == "done")
{
break;
}
lineAppear++;
istringstream convert(input);
while(convert >> ToBST)
{
o.add(ToBST,lineAppear);
}
}
o.print_inOrder(o.root);
return 0;
}
It's because you add the number both in create_new_node (which should be a constructor in BSTnode, really) and later, when if(node->data == ToBST).
You need to decide whether to add it when creating a node or afterwards, but doing it on creation makes the most sense – why would you add a node without also giving it an occurrence?
I would do like this:
class BSTnode
{
public:
string data;
vector<int> linesAppear;
BSTnode* left;
BSTnode* right;
BSTnode() : left(nullptr), right(nullptr) {}
BSTnode(const std::string& word, int appearance)
: data(word),
linesAppear(1, appearance),
left(nullptr),
right(nullptr)
{
}
};
BSTnode* BSTFCI::Insert(BSTnode* node, string ToBST,int lineAppear)
{
if(node == nullptr)
{
return new BSTnode(ToBST, lineAppear);
}
if(ToBST > node->data)
{
node->right = Insert(node->right, ToBST, lineAppear);
}
else if(ToBST < node->data)
{
node->left = Insert(node->left, ToBST, lineAppear);
}
else
{
node->linesAppear.push_back(lineAppear);
}
return node;
}
Note that there is no point in both passing node by reference and returning it, so I kept the returning and removed the reference.
You could also do the opposite.
I want to call this function in main() but problem is that what parameter I should pass in it while it receives Node type argument
In Simple I just wanna see the height of my tree. So please help me, remove the error which I face during the function call of height it needs a Node type parameter and I have no idea what should I pass. Here is the whole code
#include <iostream>
using namespace std;
// Binary Search Tree
//
class Node
{
public:
int data;
Node *left,*right;
Node(Node *l=NULL ,int d=0, Node *r=NULL)
{
left=l;
data=d;
right=r;
}
};
// Binary Search Tree
class Tree
{
Node *root;
public :
Tree()
{
root=NULL;
}
bool isEmpty()
{
if(root==NULL)
return true;
else
return false;
}
/////////////////////////////////////////////////////////////////////////////////////////////////
// insert funcation
/////////////////////////////////////////////////////////////////////////////////////////////////
void insert(int val)
{
if(isEmpty())
{
root=new Node(NULL,val,NULL);
}
else if(val < root->data && root->left==NULL)
{
Node *p=new Node(NULL ,val,NULL);
root->left=p;
}
else if(val > root->data && root->right==NULL)
{
Node *p=new Node (NULL ,val,NULL);
root->right=p;
}
else if(val < root->data)
insert(val ,root->left);
else
insert(val ,root->right);
}
////////////////////////////////////////
void insert(int val,Node *n)
{
if(val>n->data && n->right==NULL)
{
Node *p=new Node(NULL,val,NULL);
n->right=p;
}
else if(val > n->data)
insert(val,n->right);
else if(val <n->data && n->left==NULL)
{
Node *p=new Node(NULL,val,NULL);
n->left=p;
}
else
insert(val,n->left);
}
//////////////////////////////////////////////////////////////////////////////////////
// pre Order all data display
//////////////////////////////////////////////////////////////////////////////////////
void preOrder(void)
{
if(isEmpty())
cout<<"Tree is Empty\n";
else
preOrder(root);
}
void preOrder(Node *n)
{
if(n!=NULL)
{
cout<<n->data<<endl;
preOrder(n->left);
preOrder(n->right);
}
}
//////////////////////////////////////////////////////////////////////////////////////
// in fix Order all data display
//////////////////////////////////////////////////////////////////////////////////////
void inOrder()
{
if(isEmpty())
cout<<"Tree is Empty\n";
else
inOrder(root);
}
void inOrder(Node *n)
{
if(n!=NULL)
{
inOrder(n->left);
cout<<n->data<<endl;
inOrder(n->right);
}
}
//////////////////////////////////////////////////////////////////////////////////////
// post Order all data display
//////////////////////////////////////////////////////////////////////////////////////
void posOrder()
{
if(isEmpty())
cout<<"Tree is Empty\n";
else
posOrder(root);
}
void posOrder(Node *n)
{
if(n!=NULL)
{
posOrder(n->left);
posOrder(n->right);
cout<<n->data<<endl;
}
}
/////////////////////////////////////////////////////////////////////////////////////////////////
// Search funcation
/////////////////////////////////////////////////////////////////////////////////////////////////
void search(int val)
{
if(isEmpty())
cout<<"Tree is Empty\n";
else
search(val,root);
}
void search(int v,Node *p)
{
if(v==p->data)
cout<<"val : "<<p->data<<endl;
else if(v < p->data && p->left!=NULL)
search(v,p->left);
else if(v>p->data && p->right!=NULL)
search(v,p->right);
else
cout<<"Data Not Found \n";
}
Node *l;
int deleteKey(int val)
{
if(isEmpty())
cout<<"Tree is Empty\n";
else if(root->data==val &&(root->left==NULL&&root->right==NULL))
{
int temp=root->data;
delete root;
return temp;
}
else
deleteKey(val,root);
}
int deleteKey(int v,Node *p)
{
if(v == p->data)
{
if(p->left==NULL && p->right==NULL)
{
if(l->right==p)
{
int temp=p->data;
delete p;
l->right=NULL;
return temp;
}
else
{
int temp=p->data;
delete p;
l->left=NULL;
return temp;
}
}
else if(p->right!=NULL)
{
int temp=p->data;
deleteKey(p,p->right);
return temp;
}
else
{
int temp=p->data;
cout<<"Left : "<<p->data<<endl;
deleteKey(p,p->left,v);
return temp;
}
}
else if(v < p->data && p->left!=NULL)
{
l=p;
deleteKey(v,p->left);
}
else if(v>p->data &&p->right!=NULL)
{
l=p;
deleteKey(v,p->right);
}
else
cout<<"Data Not Found ----\n";
}
int deleteKey(Node *find ,Node *next)
{
if( next->left == NULL && next->right != NULL )
{
find->data = next->data;
deleteKey(find->right , next->right);
}
else if( next->left == NULL&& next->right==NULL)
{
find->data = next->data;
delete next;
find->right=NULL;
}
else
{
Node *q;
while(next->left!=NULL)
{
q=next;
next=next->left;
}
find->data=next->data;
delete next;
q->left=NULL;
}
}
int deleteKey(Node* find,Node *next,int v)
{
if( next->right == NULL && next->left != NULL )
{
find->data = next->data;
deleteKey(find->left , next->left,v);
}
else if( next->right == NULL&& next->left==NULL)
{
find->data = next->data;
delete next;
find->left=NULL;
}
else
{
Node *q;
while(next->right!=NULL)
{
q=next;
next=next->right;
}
find->data=next->data;
delete next;
q->right=NULL;
}
}
~Tree()
{
dist();
}
void dist()
{
dist(root);
}
void dist(Node *n)
{
if(n!=NULL)
{
dist(n->left);
dist(n->right);
delete n;
}
}
int height(Node *root)
{
int h=0;
if (isEmpty())
{
cout<<"Tree is Empty\n";
}
else
{
int left_height=height(root->left);
int right_height=height(root->right);
h=1+max(left_height, right_height);
}
return h;
}
};
int main()
{
Tree obj;
obj.height();
}
Well you have to pass, root of your tree in this function, but the better approach will be if you make one more function without any parameter and make that function public and call your this private function from it by passing this->root;
Here you can see :
public:
int getHeight()
{
return height(this->root); //pass your Tree class root
}
and make that function private in class , for efficiency.
private:
int height(Node *root)
{
int h=0;
if (isEmpty())
{
cout<<"Tree is Empty\n";
}
else
{
int left_height=height(root->left);
int right_height=height(root->right);
h=1+max(left_height, right_height);
}
return h;
}
Another, approach is to make a getRoot() function in class and get Root of Tree class in main and pass to height function. But The first approach will be better.
My InsertInTree function is not working properly, and I am not able to figure out my problem. Please suggest changes I can make (but I don't want to use recursion).
It takes values from the structure and the function GetNewNode returns the node with left and right pointer as NULL:
public:
void InsertInTree(int piData)
{
Node*newNode = NULL;
newNode=GetNewNode(piData);
if(root==NULL)
{
root=newNode;
return;
}
Node*temp = root;
while(temp!=NULL)
{
if(newNode->data<=temp->data)
{
temp=temp->left;
}
else
{
temp=temp->right;
}
}
temp=newNode;
return;
}
bool SearchNum(int piSearch)
{
if(root==NULL)
{
return false;
}
Node*temp=root;
while(temp!=NULL)
{
if(temp->data==piSearch)
{
return true;
}
else if(piSearch<=temp->data)
{
temp=temp->left;
}
else
{
temp=temp->right;
}
}
if(temp==NULL)
{
return false;
}
else
{
return true;
}
}
Assuming root is global. you should use one more node i.e. *pre (previousnode).
*pre=NULL;
while(temp!=NULL){
if(newnode->data<=temp->data){
pre=temp;
temp=temp->left;
}else{
pre=temp;
temp=temp->right;
}
}
if(newnode->data<=pre->data)
pre->left=newnode;
else
pre->right=newnode;
this will solve the problem..
The following should fix your issue:
void InsertInTree(int piData)
{
Node* newNode = GetNewNode(piData);
Node** temp = &root;
while (*temp != NULL)
{
if (newNode->data <= (*temp)->data)
{
temp = &(*temp)->left;
}
else
{
temp = &(*temp)->right;
}
}
*temp = newNode;
}
This is a binary search tree implementation, I cant figure out why my min method (for finding the minimum element in a tree) is not returning the correct answer, but an arbitrary memory address.
I am creating a tree by this constructor BST(3);, now I run min(), it returns correctly 3, but after inserting 1(insert(1) method), min() returns some hex address.
class node{
public:
int key;
node *left;
node *right;
node *parent;
};
class BST{
node *root;
public:
BST(){}
BST(int a){
root=new node();
root->left=NULL;
root->right=NULL;
root->parent=NULL;
root->key=a;
}
void insert(int n)
{
if(search(n))return;
node *p=root;
node *m=new node;
m->key=n;
m->left=NULL;
m->right=NULL;
while(1)
{
if(p->key > n)
{
//look left
if(p->left==NULL)
{
p->left=m;
m->parent=p;
return;
}
else
p=p->left;
}
else
{
//look right
if(p->right==NULL)
{
p->right=m;
m->parent=p;
return;
}
else
p=p->right;
}
}
}
bool search(int n)
{
node *p=root;
while(1)
{
if(p->key > n)
{
//look left
if(p->left==NULL)
return false;
else
p=p->left;
}
else if(p->key==n)return true;
else
{
//look right
if(p->right==NULL)
return false;
else
p=p->right;
}
}
}
int min()
{
node *p=root;
if(p->left == NULL)
return (p->key);
p=p->left;
}
};
Because you run into undefined behaviour by not returning on all control paths:
int min()
{
node *p=root;
if(p->left == NULL)
return (p->key);
p=p->left;
//no return here
}
Which means that if p->left is not NULL, anything can happen. Anything!
It looks like you want a loop there instead:
int min()
{
node *p=root;
while (p->left != NULL)
p=p->left;
return (p->key);
}
If p->left != NULL, you don't return anything.