recursive code for finding the height of a binary tree - c++

I am trying to find the height of a binary tree and here is my attempt at the same
#include<iostream>
#include<stack>
using namespace std;
int total = 0;
int length = -1;
class Node{
public:
int data;
Node *left;
Node *right;
Node(int k){
data = k;
left = right = NULL;
}
};
void height(Node *root){
if(root==NULL)
return;
length++;
if(length>total)
total = length;
height(root->left);
height(root->right);
}
int main(){
Node *root = new Node(3);
root->left = new Node(4);
root->left->left = new Node(5);
root->right = new Node(6);
root->right->left = new Node(7);
height(root);
cout<<total;
return 0;
}
here length and total have been declared as global variables having values -1 and 0 respectively.
When I run the code, the output which I am getting is the number of nodes in the tree - 1 but not the height of the tree. Please let me know my mistake here.

Sure, you're incrementing length on every node.
If you're doing it recursively, it is actually very simple:
std::size_t height(Node const *root) {
if(!root) return 0;
return 1 + std::max(height(root->left), height(root->right));
}

Your approach is more of a backtracking than a simple recursion. In this approach you should be mindful to revert back to the original state at each step. Here length is always being incremented. You should revert it back.
void height(Node *root){
if(root==NULL)
return;
length++;
total = std::max(total,length+1); // Either this or initialize length as 0
height(root->left);
height(root->right);
length--; // <--- Add this line
}

Related

Function to Calculate Height of Tree

I am struggling to understand how the following maxDepth function, which calculates the height of a tree, actually works.
Consider the tree:
1
/ \
2 3
/ \
4 5
\
8
In the code below, when we call the maxDepth function with the argument root, what is actually being calculated?
We declare two variables:
int lDepth = maxDepth(node->left);
int rDepth = maxDepth(node->right);
so for root we are assigning:
int lDepth = maxDepth(2);
int rDepth = maxDepth(3);
but there are no actual numeric values in here, so how do we call if (lDepth > rDepth) below this? There isn't anything to actually compare the values of is there? I would have thought the code in the if statement shouldn't execute.
#include <iostream>
using namespace std;
class node
{
public:
int data;
node* left;
node* right;
};
int maxDepth(node* node)
{
if (node == nullptr)
return 0;
else
{
/* compute the depth of each subtree */
int lDepth = maxDepth(node->left);
int rDepth = maxDepth(node->right);
/* use the larger one */
if (lDepth > rDepth)
return(lDepth+1);
else return(rDepth+1);
}
}
node* newNode(int data)
{
node* Node = new node();
Node->data = data;
Node->left = nullptr;
Node->right = nullptr;
return(Node);
}
int main()
{
node *root = newNode(1);
root->left = newNode(2);
root->right = newNode(3);
root->left->left = newNode(4);
root->left->right = newNode(5);
root->left->right->right = newNode(8);
cout << "Height of tree is " << maxDepth(root);
return 0;
}
We declare two variables:
int lDepth = maxDepth(node->left);
int rDepth = maxDepth(node->right);
so for root we are assigning:
int lDepth = maxDepth(2);
int rDepth = maxDepth(3);
No. We are instead finding the depths of two trees
2
/ \
4 5
\
8
and
3
The maxDepth() is a recursive function. So at the second level (one level lower to the root), there are two nodes 2 and 3.
Look at node 3 first, maxDepth(3) will allocate and call itself, then check whether there's a pointer or not, sincere there's not, it will return 0 from
if (node == nullptr)
return 0;
So rDepth is 0 for the node is 3.
Similarly, for the node 2, it will do the same, with multiple self-callings and assign an integer to the lDepth.
Thinking maxDepth() as an object instead of function might help.

Accepting tree nodes from keyboard for determining it's height

I have a code that can determine tree height by hard coding it's values
I tried using container like structures but still was not successful, instead of posting what I have tried on the part of accepting tree nodes fro the Input which is actually messy,I decided to post the code with hard coded tree nodes, what I need is for the program to accept tree nodes from the keyboard with the following helper description for input
Input:
The first line is an integer N indicating the number of nodes.
For each of the next few lines, there are two integers include a and b.b is a child of a.
example:
5 // number of nodes
1 2
1 3
3 4
3 5
in which the height will be 3
// C++ program to find height of tree
#include <bits/stdc++.h>
using namespace std;
/* A binary tree node has data, pointer to left child
and a pointer to right child */
class node
{
public:
int data;
node* left;
node* right;
};
/* Compute the "maxDepth" of a tree -- the number of
nodes along the longest path from the root node
down to the farthest leaf node.*/
int maxDepth(node* node)
{
if (node == NULL)
return 0;
else
{
/* compute the depth of each subtree */
int lDepth = maxDepth(node->left);
int rDepth = maxDepth(node->right);
/* use the larger one */
if (lDepth > rDepth)
return(lDepth + 1);
else return(rDepth + 1);
}
}
/* Helper function that allocates a new node with the
given data and NULL left and right pointers. */
node* newNode(int data)
{
node* Node = new node();
Node->data = data;
Node->left = NULL;
Node->right = NULL;
return(Node);
}
// Driver code
int main()
{
node *root = newNode(1);
root->left = newNode(2);
root->right = newNode(3);
root->left->left = newNode(4);
root->left->right = newNode(5);
cout << "Height of tree is " << maxDepth(root);
return 0;
}
Since the input identifies the parent node by its data value, we need a helper function to find it:
node *findNode(node *node, int data)
{
if (!node) return 0;
if (node->data == data) return node;
class node *found;
(found = findNode(node->left, data)) || (found = findNode(node->right, data));
return found;
}
Then we can code the input processing, e. g.:
node *node, *root = 0; // initially empty
int nn, a, b;
cin>>nn;
while (cin>>a>>b)
{
if (!root)
root = newNode(a),
node = root;
else
node = findNode(root, a);
if (!node->left) node->left = newNode(b);
else node->right = newNode(b);
}

Binary search tree traversal

Hi guys I have a doubt in inserting a new node in BST. In the addNode module I am trying to insert an element in the BST, but each time while adding a new node it is adding to the same root node which I passed from main function initially without traversing inside the tree.
This is the code which I have written.
#include<stdio.h>
#include<stdlib.h>
#include<cstdio>
#include<iostream>
using namespace std;
struct node
{
int data;
struct node *left;
struct node *right;
};
struct node* newNode(int data)
{
node* temp = (node*)malloc(sizeof(struct node));
//struct temp = new node;
temp->data = data;
temp->left = NULL;
temp->right = NULL;
return(temp);
};
int addNode(node *dest, node *root)
{
if(root == NULL)
{
cout<<"adding data to node for "<< dest->data<<endl;
root = dest;
cout<<"ROOT VALUE = root->data "<<root->data<<endl;
return 1;
}
if(dest->data > root->data)
{
cout<<"Traverse right for "<<dest->data<<endl;
addNode(dest, root->right);
}
else if(dest->data < root->data)
{
cout<<"Traverse left for "<<dest->data<<endl;
addNode(dest, root->left);
}
}
void printNodes(node *root)
{
if(root != NULL)
{
printNodes(root->left);
if(root->left != NULL && root->right != NULL)
std::cout<< root->data <<" ";
printNodes(root->right);
}
}
int main()
{
int i, j, k, flag;
int arr[6] = {4, 2,8, 1, 0, 10};
node *start = newNode(arr[0]);
for(i = 1; i < 6; i++)
{
node *newOne = newNode(0);
newOne->data = arr[i];
cout<<"NODE DATA - start->data "<<start->data;
if(addNode(newOne, start))
std::cout<<"\nNode added"<<endl;
}
printNodes(start);
return 1;
}
I am quite new to trees concept as well as pointers concept in trees. Any help is appreciated and thank you.
... but each time while adding a new node it is adding to the same root
node
This is because you are adding it always to the same root, as here
if(addNode(newOne, start))
start is always the same. You could make addNode return the new root and call it like that:
start = addNode(newOne,start);
I'll leave it to you to implement it.
Note that parameters are always passed by value in c++ (unless you pass-by-reference), thus changing the parameter inside the method, root = dest;, has no effect on the start in main.

Unable to solve: CodeForces (TwoButtons, 520B) by using binary trees

i have been trying to solve this problem by using binary trees, because i am starting to learn about them.
Please tell me if this problem can be solved by using binary trees or not, and if yes, what's wrong with my code for it that i've written so far(its in c++)?
it gives wrong answer...
The Problem:
Vasya has found a strange device. On the front panel of a device there are: a red button, a blue button and a display showing some positive integer. After clicking the red button, device multiplies the displayed number by two. After clicking the blue button, device subtracts one from the number on the display. If at some point the number stops being positive, the device breaks down. The display can show arbitrarily large numbers. Initially, the display shows number n.
Bob wants to get number m on the display. What minimum number of clicks he has to make in order to achieve this result?
Input
The first and the only line of the input contains two distinct integers n and m (1 ≤ n, m ≤ 104), separated by a space .
Output
Print a single number — the minimum number of times one needs to push the button required to get the number m out of number n.
#include <iostream>
#include <cstdio>
#include <cmath>
#include <vector>
#include <stack>
#include <queue>
using namespace std;
struct Node{
int val;
Node* Left;
Node* Right;
};
Node* GetNode(int val){
Node* newnode = new Node();
newnode->val = val;
newnode->Left = NULL;
newnode->Right = NULL;
return newnode;
}
int BFS(Node* root, int m){
int ctr = 0;
queue<Node*> qu;
qu.push(root);
while(!qu.empty()){
Node* tmp = qu.front();
qu.pop();
if(tmp->val == m) return ctr;
ctr++;
if(tmp->Left != NULL) qu.push(tmp->Left);
if(tmp->Right != NULL) qu.push(tmp->Right);
}
}
int main(void){
int n, m;
scanf("%d%d", &n, &m);
Node* root = GetNode(n);
Node* tmp;
queue<Node*> qu;
qu.push(root);
while(!qu.empty()){
tmp = qu.front();
qu.pop();
if(tmp->val == m) break;
tmp->Left = GetNode(2 * tmp->val);
qu.push(tmp->Left);
if(tmp->val-1 >= 0){
tmp->Right = GetNode(tmp->val - 1);
qu.push(tmp->Right);
}
}
printf("%d\n", BFS(root, m));
}
The while loop in your main() is an infinite loop. There are no conditions that will terminate that loop. Your program keeps allocating memory for the queue, until it runs out of space.
Your continue should be a break. Still, this while() loop is very inefficient, due to the exponentially-growing queue that it generates.
You need to store the level of the node (root level: 0) because this will give you the steps you need to get m.
struct Node{
int val;
Node* Left;
Node* Right;
int lev;
};
Then, getNode will have one more parameter(level):
Node* GetNode(int val,int l){
Node* newnode = new Node();
newnode->val = val;
newnode->lev = l;
newnode->Left = NULL;
newnode->Right = NULL;
return newnode;
}
The root of the tree starts with level 0:
Node* root = GetNode(n,0);
And when you want to get a new node the level will be the level of the parent +1:
node->Left = GetNode(value,(node->lev)+1);
Your break is not in the most efficient place, you should stop your loop when you add a new node (with value tmp->val*2 or tmp->val-1) and any of these are m (and dont forget to update tmp, you will use it to print the answer).
Another important thing to make your algorithm efficient is to know when does your node should be add in the tree. One of them is "if them is if tmp->val-1 is less or equal 0 (number must always be positive). Also, if the node is higher than m, then it shouldn't increase, so tmp->left is going to be created only if tmp->val < m.
Finally, if you reach a number that is already in your tree, then you should add that node (this validation is done with !nit.count(x) that means "if I dont have any x in my map").
//this if comes inmediatly after reading n and m
if (n==m){
cout<<0<<endl;
return 0;
}
while(!qu.empty()){
tmp = qu.front();
qu.pop();
if (!nit.count(2 * tmp->val) && (tmp->val<m)){
tmp->Left = GetNode(2 * tmp->val,tmp->lev+1);
//cout<<2 * tmp->val<<endl;
if ((2 * tmp->val)==m){
tmp=tmp->Left; break;
}
nit[2 * tmp->val]++;
qu.push(tmp->Left);
}
if(!nit.count(tmp->val-1) && (tmp->val-1 > 0)){
tmp->Right = GetNode(tmp->val - 1,tmp->lev+1);
//cout<<tmp->val-1<<endl;
if ((tmp->val-1)==m){
tmp=tmp->Right; break;
}
nit[tmp->val-1]++;
qu.push(tmp->Right);
}
}
Now you have the answer:
printf("%d\n",tmp->lev);
This is the entire code:
#include <iostream>
#include <cstdio>
#include <cmath>
#include <vector>
#include <map>
#include <stack>
#include <queue>
using namespace std;
struct Node{
int val;
Node* Left;
Node* Right;
int lev;
};
Node* GetNode(int val,int l){
Node* newnode = new Node();
newnode->val = val;
newnode->lev = l;
newnode->Left = NULL;
newnode->Right = NULL;
return newnode;
}
int main(void){
int n, m;
map<int,int>nit;
scanf("%d%d", &n, &m);
if (n==m){
cout<<0<<endl;
return 0;
}
Node* root = GetNode(n,0);
nit[n++];
Node* tmp;
queue<Node*> qu;
qu.push(root);
while(!qu.empty()){
tmp = qu.front();
qu.pop();
if (!nit.count(2 * tmp->val) && (tmp->val<m)){
tmp->Left = GetNode(2 * tmp->val,tmp->lev+1);
//cout<<2 * tmp->val<<endl;
if ((2 * tmp->val)==m){
tmp=tmp->Left; break;
}
nit[2 * tmp->val]++;
qu.push(tmp->Left);
}
if(!nit.count(tmp->val-1) && (tmp->val-1 > 0)){
tmp->Right = GetNode(tmp->val - 1,tmp->lev+1);
//cout<<tmp->val-1<<endl;
if ((tmp->val-1)==m){
tmp=tmp->Right; break;
}
nit[tmp->val-1]++;
qu.push(tmp->Right);
}
}
printf("%d\n",tmp->lev);
}
Sorry for my English c:

How to show binary search tree results in arrays?

This is my program, but I don't know how to show the binary search tree results in array (one dimensional). I use random as inputs. How to show binary search tree results in arrays? Help me please.
#include<iostream>
#include<algorithm>
using namespace std;
struct BstNode{
int data;
BstNode* left;
BstNode* right;
};
BstNode* GetNewNode(int data){
BstNode* newNode = new BstNode();
newNode->data = data;
newNode->left = newNode->right = NULL;
return newNode;
}
BstNode* Insert(BstNode* root, int data){
if(root == NULL){
root = GetNewNode(data);
}
else if(data <= root->data){
root->left = Insert(root->left,data);
}
else{
root->right = Insert(root->right,data);
}
return root;
}
int main(){
int x, i, n, data;
BstNode* root = NULL;
cout<<"The number of data : ";cin>>n;
for (i=1;i<=n;i++) {
data=(rand()%100+1);
cout<<data<<" ";
Insert(root,data);
}
}
I guess OP is looking to fill an array with the elements of BST as observed in in-order traversal. If so, we can try something like the following.
void
fillArrayInorder( BstNode const * pCurr, int * pArr, int & arrIdx ) {
if( pCurr ) {
fillArrayInorder( pCurr->left, pArr, arrIdx );
pArr[ arrIdx++ ] = pCurr->data;
fillArrayInorder( pCurr->right, pArr, arrIdx );
}
}
Call it as
int arr[ MAX_ELEMS ];
int arrIdx = 0;
fillArrayInorder( root, & arr, arrIdx );
Note: Instead of the raw array, it might be better to use a vector and its push_back() method, so that the length and index updating complexity is not necessary in the application code.