This is how my code looks
int main() {
//root is the rootnode of the tree
if(root!==NULL) {
int mini = min(root, root->data);
printf("minimum number is %d", mini);
}
return 0;
}
int min(node *root, int mini) {
if(root == NULL) {
return;
}
min(root->left, mini);
min(root->right, mini);
if(mini > root->data) {
mini = root->data;
}
return mini;
}
It doesn't give me the minimum number in the tree. Rather, it prints the root node as the minimum.
You need to use the results of the recursive calls instead of throwing them away.
They are supposed to be the minimum values of the subtrees.
The minimum value in a tree is the minimum of
The root value
The value in the left subtree, if there is one
The value in the right subtree, if there is one
Like this:
int min(node *root)
{
int least = root->data;
if (root->left != NULL)
{
least = std::min(least, min(root->left));
}
if (root->right != NULL)
{
least = std::min(least, min(root->right));
}
return least;
}
Try this:
int min(node *root, int mini) {
if(root == NULL) {
return -1;
}
int a;
a=min(root->left, mini);
if(a<mini)
mini=a;
a=min(root->right, mini);
if(a<mini)
mini=a;
if(root->data<mini)
mini = root->data;
return mini;
}
This works for me. Not discarding the return value.
int main() {
//root is the rootnode of the tree
if(root!==NULL) {
int mini = min(root, root->data);
printf("minimum number is %d", mini);
}
return 0;
}
int min(node *root, int mini) {
if(root == NULL) {
return;
}
mini = min(root->left, mini);
mini = min(root->right, mini);
if(mini > root->data) {
mini = root->data;
}
return mini;
}
Related
i tried building a binary search tree, everything worked fine when i gave it parameters that were in in the tree, but i wanted to see if it would print 0 when it couldn't find the int in the tree instead when i call search it's crashing.
i tried adding a condition after the first if statement but that ruined the recursion
here's the code:
struct node
{
int data;
node* left;
node* right;
node(int d)
{
data = d;
left = right = NULL;
}
};
node* insert(node *root, int n)
{
if(root == NULL)
{
return new node(n);
}
else
{
node* y;
if(n <= root->data)
{
y = insert(root->left, n);
root->left = y;
}
else
{
y = insert(root->right, n);
root->right = y;
}
return root;
}
}
node* search(node *root,int n)
{
if(root == NULL || root->data == n)
{
return root;
}
if(root->data < n)
{
return search(root->right, n);
}
return search(root->left, n);
}
int treemax(node *root)
{
while(root->right != NULL)
{
root = root->right;
}
return root->data;
}
int treemin(node *root)
{
while(root->left != NULL)
{
root = root->left;
}
return root->data;
}
int main()
{
node *R = NULL;
R = insert(R, 33);
insert(R,12);
insert(R, 40);
insert(R, 36);
insert(R, 21);
cout << search(R, 65)->data << endl;
}
Your problem is that you are trying to access null pointer. Pointer returned from search(R,65) is null because аt last step your root->right is null.
If you want to return 0 if no elements is found you can replace your last line with this:
node *result = search(R, 65);
if (result)
cout << result->data << endl;
else
cout << "0" << endl;
Below is a working example. I have added some comments that show what things you can change in the above program to make it safe or better.
#include<iostream>
struct node
{
//always initialize built-in type data members
int data = 0;//initialize any built in type otherwise it will have garbage value
node* left = nullptr;//initialize any built type as stated above
node* right = nullptr;//initialize any built in type as stated above
node(int d)
{
data = d;
left = right = nullptr;
}
};
node* insert(node *root, int n)
{
if(root == nullptr)
{
return new node(n);
}
else
{
node* y;
if(n <= root->data)
{
y = insert(root->left, n);
root->left = y;
}
else
{
y = insert(root->right, n);
root->right = y;
}
return root;
}
}
node* search(node *root,int n)
{
if(root == nullptr || root->data == n)
{
return root;
}
if(root->data < n)
{
return search(root->right, n);
}
return search(root->left, n);
}
int treemax(node *root)
{
while(root->right != nullptr)
{
root = root->right;
}
return root->data;
}
int treemin(node *root)
{
while(root->left != nullptr)
{
root = root->left;
}
return root->data;
}
int main()
{
node *R = nullptr;
R = insert(R, 33);
insert(R,12);
insert(R, 40);
insert(R, 36);
insert(R, 21);
//std::cout << search(R, 65)->data << std::endl;
node *value = search(R, 65);
//check if the pointer is valid
if(value)
{
std::cout<< value->data <<std::endl;
}
else
{
std::cout<<"cannot access nullptr"<<std::endl;
}
}
The error was because search(R, 65); was returning NULL and you were trying to access a NULL pointer's data member value.
When you run
cout << search(R, 65)->data << endl;
search(R, 65) returns NULL. You can't dereference NULL by doing ->data on it. You probably want:
Node* result = search(R, 65);
if (result)
{
cout << result->data << endl;
}
else
{
cout << "Not found" << endl;
}
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
https://practice.geeksforgeeks.org/problems/maximum-path-sum/1
this is question from geeks for geeks. i wrote my ans. but it is giving wrong. what is problem with my logic?
int path(Node *root, int & max_sum)
{
if(root==NULL)
return 0;
int l=path(root->left,max_sum);
int r=path(root->right,max_sum);
max_sum=max(max_sum,l+r+root->data);
return max(l,r)+root->data;
}
int maxPathSum(Node *root)
{
int max_sum=INT_MIN;
path(root,max_sum);
return max_sum;
// code here
}
The problem statement says
Find the maximum possible sum from one leaf node to another.
So, when you do
max_sum=max(max_sum,l+r+root->data);
You will need to check whether the root has both the children. Otherwise, they won't be considered in the final answer.
You also did
if(root==NULL) return 0;
and
max(l,r)+root->data;
These both combined are overriding a single leaf node child whose value is negative since 0 is greater than any negative integer.
So overall your code should look like this:
int path(Node *root, int & max_sum)
{
if(root==NULL) return 0;
int l=path(root->left,max_sum);
int r=path(root->right,max_sum);
if(root->left != NULL && root->right != NULL){
max_sum = max(max_sum,l + r + root->data);
}
if(root->left != NULL && root->right == NULL) return l + root->data;
if(root->right != NULL && root->left == NULL) return r + root->data;
return max(l,r) + root->data;
}
int maxPathSum(Node *root)
{
int max_sum=INT_MIN;
path(root,max_sum);
return max_sum;
}
If I was asked about number of nodes in binary tree, it would be so easy but I am asked to count number of distinct nodes in binary tree like below.
There are two 12 values!
Number of nodes in binary tree algoritm is this:
struct Node {
string data;
struct Node *left;
struct Node *right;
};
int getNumberOfNodes(Node* node)
{
if (node != NULL)
return getNumberOfNodes(node->left) + 1 + getNumberOfNodes(node->right);
else
return 0;
}
But for unique values, it is too hard -_-
You can change your function adding a container to maintain the values you already encountered. The best container has been suggested in the comment std::set.
The new code would be:
int getNumberOfNodes(Node* node, std::set<string>& uniqueValues)
{
if (node != NULL)
{
int count = 0;
if ( uniqueValues.find( node->data ) == uniqueValues.end() )
{
count = 1;
uniqueValues.insert ( node->data );
}
return getNumberOfNodes(node->left,uniqueValues) + count + getNumberOfNodes(node->right,uniqueValues);
}
else
return 0;
}
Not so different from your code.
At the end the uniqueValues.size() will be equal to the returned int.
Clear the uniqueValues before calling the function.
int count_label(Node *root, int data)
{
int count_of_data = 0;
if(root == NULL)
return 0;
if(data == root->data)
count_of_data += 1;
if(data > root->data)
count_of_data += count_label(root->right,data);
else
count_of_data += count_label(root->left,data);
return count_of_data;
}
//--------------------------------------------------------
unsigned int unique_nodes(Node *root)
{
int count_u = 0;
if(root == NULL)
return 0;
if(count_label(root, root->data) == 1)
{
count_u += 1;
}
count_u += unique_nodes(root->left);
count_u += unique_nodes(root->right);
return count_u;
}
I'm writing a function that counts the leaf nodes of a height balanced tree using struct and pointers. The function takes 3 arguments: the tree, pointer to an array and the maximum depth of the tree. The length of the array is the maximum depth. When function is called the array is initialized to zero. The function recursively follows the tree structure,
keeping track of the depth, and increments the right counter whenever it reaches a leaf. The function does not follow any pointer deeper than maxdepth. The function returns 0 if there was no leaf at depth greater than maxdepth, and 1 if there was some pointer togreater depth. What is wrong with my code. Thanks.
typedef int object;
typedef int key;
typedef struct tree_struct { key key;
struct tree_struct *left;
struct tree_struct *right;
int height;
} tree_n;
int count_d (tree_n *tr, int *count, int mdepth)
{
tree_n *tmp;
int i;
if (*(count + 0) == NULL){
for (i =0; i<mdepth; i++){
*(count + i) = 0;
}
}
while (medepth != 0)
{
if (tr == NULL) return;
else if ( tree-> left == NULL || tree->right == NULL){
return (0);
}
else {
tmp = tr;
*(count + 0) = 1;
int c = 1;
while(tmp->left != NULL && tmp->right != NULL){
if(tmp-> left){
*(count + c) = 2*c;
tmp = tmp->left;
return count_d(tmp, count , mdepth);
}
else if(tmp->right){
*(count + c + 1) = 2*c + 1;
tmp = tmp->right;
return count_d(tmp,count, mdepth);
}
c++;
mpth--;
}
}
}
What is wrong with my code
One thing I noticed is that you are missing return in the recursive calls.
return count_d(tmp, count , mdepth);
// ^^^ Missing
There are two such calls. Make sure to add return to both of them.
Disclaimer: Fixing this may not fix all your problems.
Correct Function To Insert,Count All Nodes and Count Leaf Nodes
#pragma once
typedef int itemtype;
#include<iostream>
typedef int itemtype;
#include<iostream>
#include<conio.h>
#include<string>
using namespace std;
class Node
{
public:
Node* left;
Node* right;
itemtype data;
};
class BT
{
private:
int count = 0;
Node* root;
void insert(itemtype d, Node* temp);//Override Function
public:
BT();//Constructor
bool isEmpty();
Node* newNode(itemtype d);
Node* getroot();
void insert(itemtype d);//Function to call in main
int countLeafNodes(Node * temp);
int countAllNodes();//to count all nodes
}
BT::BT()//constructor
{
root = NULL;
}
bool BT::isEmpty()
{
if (root == NULL)
return true;
else
return false;
}
Node* BT::newNode(itemtype d)
{
Node* n = new Node;
n->left = NULL;
n->data = d;
n->right = NULL;
return n;
}
void BT::insert(itemtype d)//Function to call in main
{
if (isEmpty())
{
Node* temp = newNode(d);
root = temp;
}
else
{
Node* temp = root;
insert(d, temp);
}
count++;//to count number of inserted nodes
}
void BT::insert(itemtype d, Node* temp)//Private Function which is overrided
{
if (d <= temp->data)
{
if (temp->left == NULL)
{
Node* n = newNode(d);
temp->left = n;
}
else
{
temp = temp->left;
insert(d, temp);
}
}
else
{
if (temp->right == NULL)
{
temp->right = newNode(d);
}
else
{
temp = temp->right;
insert(d, temp);
}
}
}
int BT::countAllNodes()
{ return count; }
int BT::countLeafNodes(Node* temp)
{
int leaf = 0;
if (temp == NULL)
return leaf;
if (temp->left == NULL && temp->right == NULL)
return ++leaf;
else
{
leaf = countLeafNodes(temp->left) + countLeafNodes(temp->right);
return leaf;
}
}
void main()
{
BT t;
t.insert(7);
t.insert(2);
t.insert(3);
t.insert(15);
t.insert(11);
t.insert(17);
t.insert(18);
cout<<"Total Number Of Nodes:" <<t.countAllNodes() <<endl;
cout << "Leaf Nodes:" << t.countLeafNodes(t.getroot()) << endl;
_getch();
}
Output:
Ouput