not able to create Binary search tree in c++ - c++

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;
}

Related

How to implement complete binary in c++?

I want to try make insertion of complete binary tree using recursion . I make a piece of code and I cannot catch problem why value not inserted. I make height function and count nodes function with help of these function and recursive call I want to insert new node in Complete binary tree. In main get root by using get root function then send to insert function
#include<iostream>
#include<math.h>
using namespace std;
struct node{
int data;
node *left,*right;
};
class cbt{
node *root;
public:
cbt()
{
root=NULL;
}
node* get_node()
{
return root;
}
node* newNode(int key)
{
node* temp1 = new node;
temp1->data = key;
temp1->left = temp1->right = NULL;
return temp1;
}
void CBT_inseration(node* temp,int data)
{
node *ptr;
ptr=newNode(data);
if(root==NULL)
{
root=ptr;
return;
}
else
{
height = f_height(temp->left);
int excepted_node = pow(2,height)-1;
int left_tree_node_count = countNumNodes(temp->left);
int right_tree_node_count = countNumNodes(temp->right);
if(left_tree_node_count==right_tree_node_count)
{
CBT_inseration(temp->left,data);
}
else if(excepted_node != left_tree_node_count)
{
if(temp->left == NULL)
{
temp->left = ptr;
return;
}else
{
CBT_inseration(temp->left,data);
}
}
else if(temp->right == NULL)
{
temp->right=ptr;
return;
}
else if(excepted_node != left_tree_node_count)
{
if(temp->left == NULL)
{
temp->left=ptr;
return;
}
else
{
CBT_inseration(temp->right,data);
}
}
}
}
void print(node *root) {
if (root == NULL)
return;
print(root->left);
cout << root->data << " ";
print(root->right);
}
};
int main()
{
cbt obj;
node *r=NULL;
obj.CBT_inseration(obj.get_node(),4);
obj.CBT_inseration(obj.get_node(),3);
obj.CBT_inseration(obj.get_node(),5);
obj.CBT_inseration(obj.get_node(),8);
obj.print(obj.get_node());
return 0;
}
You would need to go through a debugger to see what is wrong with your code. I will tell you how I would do this:
First, you need a function to check if the tree is full. We will reuse your functions to do this:
bool isTreeFull(node* head) {
return head != NULL && countNumNodes(head) == (1 << find_height(head)) - 1;
}
Then for inserting I have to check if the number of nodes on each side are the same. This tells me that I am allowed to move one level deeper on the left side. If the number of nodes aren't the same, then I only move on to insert on the right subtree if the left subtree is full:
void CBT_inseration(int data) {
root = insert(root, data);
}
node* insert(node* head, int data) {
if (head == NULL) {
head = newNode(data);
} else {
int leftCount = countNumNodes(head->left);
int rightCount = countNumNodes(head->right);
if (leftCount == rightCount) {
head->left = insert(head->left, data);
} else {
if (isTreeFull(head->left)) {
head->right = insert(head->right, data);
} else {
head->left = insert(head->left, data);
}
}
}
return head;
}
Then you would call it like:
cbt obj;
obj.CBT_inseration(4);
obj.CBT_inseration(3);
obj.CBT_inseration(5);
obj.CBT_inseration(6);
obj.CBT_inseration(8);
obj.print(obj.get_node()); // 6 3 8 4 5

how to reset the pointer in BST?

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;
}

Finding an element in Binary Search Tree

I wrote this code to find a node in BST.The code works fine for Nodes found but the code crashes when a node is not found.
What is the possible error in my code?
TreeNode* fetch(TreeNode*root,int d)
{
if(root->data==d)
{
return root;
}
else if(root==NULL)
{
return NULL;
}
else if(d<root->data)
{
return fetch(root->left,d);
}
else if(d>root->data)
{
return fetch(root->right,d);
}
}
TreeNode* temp;
temp=fetch(root,d);
if(temp->data)
{
cout<<temp->data<<" FOUND";
}
else if(temp==NULL)
{
cout<<"Not Found";
}
You need to adjust your ordering in your fetch() function. Right now, it will error if root==NULL because it first checks if the data in the potentially non-existent node is equal to d. Fixed is as follows:
TreeNode* fetch(TreeNode*root,int d)
{
if(root==NULL)
{
return NULL;
}
else if(root->data==d)
{
return root;
}
else if(d<root->data)
{
return fetch(root->left,d);
}
else if(d>root->data)
{
return fetch(root->right,d);
}
}
Additionally you need to reorder your check at the bottom for the same reason:
if(temp==NULL)
{
cout<<"Not Found";
}
else
{
cout<<temp->data<<" FOUND";
}
The problem is with the sequence of conditions put in if else if ladder.
Please read the comments I have written on the lines of your code
TreeNode* fetch(TreeNode*root,int d)
{
if(root->data==d) /* if d doesn't exists, root becomes
null and dereferencing a null
gives error, i.e, null->data is
error. So, first root=null should
be checked*/
{
return root;
}
else if(root==NULL)
{
return NULL;
}
else if(d<root->data)
{
return fetch(root->left,d);
}
else if(d>root->data)
{
return fetch(root->right,d);
}
}
TreeNode* temp;
temp=fetch(root,d);
if(temp->data) // temp=NULL should be must codition
{
cout<<temp->data<<" FOUND";
}
else if(temp==NULL)
{
cout<<"Not Found";
}
You have no case if a node is a leaf. Before you call fetch(root->left,d) or fetch(root->right,d) make sure the node has a left or right element by checking if(root->(left/right) != NULL) before you call fetch again. If they do == NULL, then you can return NULL as you've navigated to the bottom of the tree and didn't find your element.

Error when Deleting Node from BST

This genuinely has me stumped. I have a binary search tree of citys that is ordered by the city name. A city also contains the population and GPS coordinates. I want to be able to remove nodes from the tree by City name or city coordinates. I have the delete by name working fine but the GPS coordinates does not work.
When I remove a node by GPS I get a stack-overflow when I try to print the binary tree. Below is some of my code. I cannot understand how it will work fine if I delete by name but not if I delete by coordinates as I am using the same delete method.
The exact error I get is "Unhandled exception at 0x013214D6 in EXE: 0xC00000FD: Stack overflow (parameters: 0x00000001, 0x00152FFC)." This occurs in my print function after I delete by coordinates but not if I delete by name.
bool BinaryTree::DeleteByName(string city)
{
if (GetRoot() != NULL)
{
return (DeleteByName(GetRoot(), city));
}
return false;
}
TreeNode* BinaryTree::DeleteByName(TreeNode *node, string city)
{
if (node == NULL)
{
return node;
}
else if (city < node->Data.name)
{
node->Left = DeleteByName(node->Left, city);
}
else if (city > node->Data.name)
{
node->Right = DeleteByName(node->Right, city);
}
else
{
if (node->Left == NULL && node->Right == NULL)
{
delete node;
node = NULL;
}
else if (node->Left == NULL)
{
TreeNode* temp = node;
node = node->Right;
delete temp;
}
else if (node->Right == NULL)
{
TreeNode* temp = node;
node = node->Left;
delete temp;
}
else
{
cout << "Else";
TreeNode* temp = MinPtr(node->Right);
node->Data = temp->Data;
node->Right = DeleteByName(node->Right, temp->Data.name);
}
}
return node;
}
bool BinaryTree::DeleteByCoord(pair<double, double> coords)
{
if (GetRoot() == NULL)
{
return false;
}
else
{
return DeleteByCoord(GetRoot(), coords);
}
}
bool BinaryTree::DeleteByCoord(TreeNode* node, pair<double, double> coords)
{
bool result;
if (node == NULL)
{
return false;
}
else
{
if (node->Data.coordinates.first == coords.first && node->Data.coordinates.second == coords.second)
{
return (DeleteByName(node, node->Data.name));
}
result = DeleteByCoord(node->Left, coords);
if (result == true)
{
return result;
}
return DeleteByCoord(node->Right, coords);
}
}
void BinaryTree::Insert(City city)
{
TreeNode* temp = new TreeNode(city);
if (GetRoot() == NULL)
{
root = temp;
}
else
{
Insert(temp, GetRoot());
}
}
void BinaryTree::Insert(TreeNode* toAdd, TreeNode* addHere)
{
if (toAdd->Data < addHere->Data)
{
if (addHere->Left != NULL)
{
Insert(toAdd, addHere->Left);
}
else
{
addHere->Left = toAdd;
}
}
else if (toAdd->Data > addHere->Data)
{
if (addHere->Right != NULL)
{
Insert(toAdd, addHere->Right);
}
else
{
addHere->Right = toAdd;
}
}
}
void BinaryTree::InOrderTraversal(TreeNode* node)
{
if (node != NULL)
{
InOrderTraversal(node->Left);
cout << node->Data << endl;
InOrderTraversal(node->Right);
}
}
void BinaryTree::InOrderTraversal()
{
InOrderTraversal(GetRoot());
}
TreeNode* BinaryTree::GetRoot()
{
return root;
}
TreeNode* BinaryTree::MinPtr(TreeNode* node)
{
while (node->Left != NULL)
{
node = node->Left;
}
return node;
}
When you delete the node you also need to update parent pointer that points to deleted node. Pay attention here:
when you call DeleteByName directly it searches required node and returns NULL pointer which automatically set to parent node pointer:
else if (city < node->Data.name)
{
node->Left = DeleteByName(node->Left, city);
}
else if (city > node->Data.name)
{
node->Right = DeleteByName(node->Right, city);
}
but when you call DeleteByName from coordinates method you do not reset parent's Left/Right pointers:
if (node->Data.coordinates.first == coords.first && node->Data.coordinates.second == coords.second)
{
return (DeleteByName(node, node->Data.name));
}
in its turn as DeleteByName already receives required node, it does not perform recursive call and does not reset parent's pointers either:
else
{
if (node->Left == NULL && node->Right == NULL)
{
delete node;
node = NULL;
}
//... same here
}
NOTE: There are many more problems in your code. Some that strike the eye:
DeleteByName returns pointer, but DeleteByCoord returns bool, you use pointer as a boolean type in DeleteByCoord
Avoid to compare doubles directly, the comparison result can be wrong. See the question and explanation for the details.

Removing a Node in a BST

I am having trouble getting my remove300 and removeNode300 function working correctly when I remove the root of the tree. (In my case 8). Everything works right(compiling wise), but when I call me inView function, which displays the numbers in the binary tree in ascending order, it takes that 8 out and just puts the highest number in 8's place.
For example:
I insert these numbers in this order, 8,4,12,2,6,10,14,20 and call me remove function to remove 8. I get this output 2,4,5,20,10,12,14. I want it to be 2,4,6,10,12,14,20.
If I can get some help on this on why this process isn't working please let me know. Also let me know if I have to add anything to this post inorder to help you.
Struct definition:
typedef float Element300;
struct TreeNode300;
typedef TreeNode300 * TreePtr300;
struct TreeNode300
{
Element300 element;
TreePtr300 left;
TreePtr300 right;
};
Remove Function:
void BST300::remove300(const Element300 element, TreePtr300 & root)
{
if(root == NULL)
{
cerr << "Error: Remove Failed!" << endl;
}
else if(element == root->element )
{
removeNode300(root);
}
else if(element < root->element)
{
remove300(element, root->left);
}
else
{
remove300(element, root->right);
}
return;
}
Remove Node function:
void BST300::removeNode300(TreePtr300 & root)
{
TreePtr300 tempPointer = NULL;
if(root->left == NULL && root->right == NULL)
{
delete root;
root = NULL;
}
else if(root->right == NULL)
{
tempPointer = root;
root = root->left;
tempPointer->left = NULL;
delete tempPointer;
}
else if(root->left == NULL)
{
tempPointer = root;
root = root->right;
tempPointer->right = NULL;
delete tempPointer;
}
else
{
findMaxNode300(root->right, tempPointer);
root->element = tempPointer->element;
delete tempPointer;
}
tempPointer = NULL;
return;
}
find Maximum value function:
void BST300::findMaxNode300(TreePtr300 & root, TreePtr300 & tempPointer)
{
if(root->right == NULL)
{
tempPointer = root;
root = root->left;
tempPointer->left = NULL;
}
else
{
findMaxNode300(root->right, tempPointer);
}
return;
}