I'm trying to build simple structure in C++. It should be similar to AVL tree.
Everything is OK when I build a simple tree with three nodes in main() function.
The problem is when I try use insert() function. The first argument of this function contains information where put the value from the second argument.
Here is the code:
#include <numeric>
#include <vector>
#include <cstdio>
#include <cstdlib>
using namespace std;
struct Node {
Node* left;
Node* right;
Node* parent;
int value;
int count_leafs;
int height;
};
Node* root;
void insert2(int p, int value, Node* node, int left)
{
//printf("insert %d %d - (%d, %d) %d \n", p, value, node->left, node->right, left);
if (root == NULL) {
// creating a tree root
Node new_node;
new_node.left = NULL;
new_node.right = NULL;
new_node.parent = NULL;
root = &new_node;
root->value = value;
root->count_leafs = 1;
root->height = 1;
return;
}
if (node->left == NULL && node->right == NULL) {
// joining value to the leaf
Node new_parent;
new_parent.count_leafs = 2;
new_parent.height = 2;
new_parent.value = node->value + value;
new_parent.parent = node->parent;
new_parent.left = NULL;
new_parent.right = NULL;
Node new_leaf;
new_leaf.value = value;
new_leaf.count_leafs = 1;
new_leaf.left = NULL;
new_leaf.right = NULL;
new_leaf.height = 1;
new_leaf.parent = &new_parent;
new_parent.left = &new_leaf;
new_parent.right = node;
if (node->parent != NULL && node->parent->left != NULL && node->parent->left == node) {
printf("a");
node->parent->left = &new_parent;
}
if (node->parent != NULL && node->parent->right != NULL && node->parent->right == node) {
printf("b");
node->parent->right = &new_parent;
}
node->parent = &new_parent;
return;
}
//printf("GOTO: %d %d \n", left + node->left->count_leafs, p);
node->value += value;
node->count_leafs += 1;
if (left + node->left->count_leafs + 1 >= p) {
//printf("W left\n");
insert2(p, value, node->left, left);
} else {
//printf("W right\n");
insert2(p, value, node->right, left + node->left->count_leafs);
}
}
void insert(int p, int value)
{
insert2(p, value, root, 0);
}
int main()
{
Node new_root;
root = NULL;
new_root.value = 10;
new_root.height = 2;
new_root.count_leafs = 2;
new_root.parent = NULL;
root = &new_root;
Node left;
left.value = 6;
left.height = 1;
left.count_leafs = 1;
left.parent = root;
left.left = NULL;
left.right = NULL;
Node right;
right.value = 4;
right.height = 1;
right.count_leafs = 1;
right.parent = root;
right.left = NULL;
right.right = NULL;
root->left = &left;
root->right = &right;
// PLACE A
insert(0, 1);
// PLACE B
return 0;
}
As you see before PLACE A is building a tree with 3 nodes. It look like this in PLACE A:
10
/ \
6 4
Next, in a line between PLACE A and PLACE B, I want to add a new node. After that (in PLACE B) the tree should looks like this:
11
/ \
7 4
/ \
1 6
But I gets something like this:
11
/ \
1972250912 4
/ \
2 2
I can't figure out what is wrong. It should be the problem in insert2() function, but I can't find it.
Do you see it?
Thanks in advance for you help!
The cause of a such behavior is that you use scope variables out of the scope. You must not use the pointer that points to the scope variable out of that scope. Scope variables exists only withing the scope were they were declared. If decide to access a scope variable out of the scope, you will access some piece of stack that would have some other data overwritten that variable that would result in undefined behavior.
I mean, that you must NOT do like this:
if (root == NULL)
{
Node new_node;
root = &new_node;
return;
}
You may use operator new to create a new instance of struct Node in the heap and use it later.
if (root == NULL)
{
root = new Node;
return;
}
But you have to delete this node later. Or you may use smart pointers, see this.
Read this and this for more information.
The code below do just what you expected. However it does not delete created nodes that would result in memory leak, so this code have to be improved, but this is a separate issue.
#include <numeric>
#include <vector>
#include <cstdio>
#include <cstdlib>
using namespace std;
struct Node {
Node* left;
Node* right;
Node* parent;
int value;
int count_leafs;
int height;
};
Node* root;
void insert2(int p, int value, Node* node, int left)
{
//printf("insert %d %d - (%d, %d) %d \n", p, value, node->left, node->right, left);
if (root == NULL) {
// creating a tree root
Node* new_node = new Node;
new_node->left = NULL;
new_node->right = NULL;
new_node->parent = NULL;
root = new_node;
root->value = value;
root->count_leafs = 1;
root->height = 1;
return;
}
if (node->left == NULL && node->right == NULL) {
// joining value to the leaf
Node* new_parent = new Node;
new_parent->count_leafs = 2;
new_parent->height = 2;
new_parent->value = node->value + value;
new_parent->parent = node->parent;
new_parent->left = NULL;
new_parent->right = NULL;
Node* new_leaf = new Node;
new_leaf->value = value;
new_leaf->count_leafs = 1;
new_leaf->left = NULL;
new_leaf->right = NULL;
new_leaf->height = 1;
new_leaf->parent = new_parent;
new_parent->left = new_leaf;
new_parent->right = node;
if (node->parent != NULL && node->parent->left != NULL && node->parent->left == node) {
printf("a");
node->parent->left = new_parent;
}
if (node->parent != NULL && node->parent->right != NULL && node->parent->right == node) {
printf("b");
node->parent->right = new_parent;
}
node->parent = new_parent;
return;
}
//printf("GOTO: %d %d \n", left + node->left->count_leafs, p);
node->value += value;
node->count_leafs += 1;
if (left + node->left->count_leafs + 1 >= p) {
//printf("W left\n");
insert2(p, value, node->left, left);
}
else {
//printf("W right\n");
insert2(p, value, node->right, left + node->left->count_leafs);
}
}
void insert(int p, int value)
{
insert2(p, value, root, 0);
}
int main()
{
Node new_root;
root = NULL;
new_root.value = 10;
new_root.height = 2;
new_root.count_leafs = 2;
new_root.parent = NULL;
root = &new_root;
Node left;
left.value = 6;
left.height = 1;
left.count_leafs = 1;
left.parent = root;
left.left = NULL;
left.right = NULL;
Node right;
right.value = 4;
right.height = 1;
right.count_leafs = 1;
right.parent = root;
right.left = NULL;
right.right = NULL;
root->left = &left;
root->right = &right;
// PLACE A
insert(0, 1);
// PLACE B
return 0;
}
Related
So I'm making a binary max heap for my c++ class and I keep encountering this exception saying that I'm returning a nullptr in my class methods. I'm having trouble finding where it could be at in my code so any help would be greatly appreciated. The exception that keeps getting thrown is as follows:
Unhandled exception thrown: read access violation.
**std::_String_alloc<std::_String_base_types<char,std::allocator<char> > ::_Get_data**(...) returned nullptr. occurred
Here's my header file for the tree:
#ifndef HEAP_H
#define HEAP_H
#include <iostream>
#include "THeapNode.h"
class TreeHeap {
private:
THeapNode *root; // the top node of the heap
int next_loc; // the next valid location to place a node
void bubble_up(THeapNode *node); //performs the bubble up operation on the given node
void bubble_down(THeapNode *node); //performs the bubble down operation on the given node
void clear_heap(THeapNode *node); // removes all elements from the heap
public:
TreeHeap(); // the constructor
~TreeHeap(); // the destructor
THeapNode* find_node(const int position); // finds the node in the position given and returns a pointer to it
void insert(const string &item); // creates a node with the string given as the value and places it in the next location
bool Delete(); // removes the root of the heap and returns false if the tree is empty
};
#endif
Here's my Node's .h file:
#ifndef NODE_H
#define NODE_H
#include<string>
using std::string;
struct THeapNode {
string data; // stores a data string
THeapNode *parent; // a pointer to the parent node
THeapNode *rightChild; // a pointer to the right child node
THeapNode *leftChild; // a pointer to the left child node
THeapNode( const string &str );
};
#endif
And here's my .cpp file:
#include "stdafx.h"
#include <cmath>
#include "TreeHeap.h"
#include "THeapNode.h"
TreeHeap::TreeHeap() {
root = NULL;
next_loc = 1;
};
TreeHeap::~TreeHeap() {
THeapNode *current = root;
THeapNode *deleteNode = NULL;
int d = floor(log2(next_loc - 1));
int j = next_loc;
for ( int i = 1; i <= j-1; i++ ) {
while (1) {
int d = floor(log2(next_loc - i));
int power = std::pow(2, d - 1);
if (next_loc == 1) {
deleteNode = current;
j -= 1;
}
else if (next_loc < (std::pow(2, d - 1) * 3)) {
current = current->leftChild;
}
else {
current = current->rightChild;
}
// Update location and depth to reflect traversal
next_loc = std::pow(2, d - 1) + next_loc % power;
d = d - 1;
}
clear_heap(deleteNode);
}
}
void TreeHeap::clear_heap(THeapNode *node) {
if (node == NULL) {
return;
}
node->data = "";
node->leftChild = NULL;
node->rightChild = NULL;
node->parent = NULL;
}
void TreeHeap::insert( const string &value ) {
THeapNode newNode = THeapNode(value);
int loc = next_loc;
if (loc == 1) {
*root = newNode;
}
THeapNode *current = root;
while (1) {
int d = floor(log2(loc));
int power = std::pow(2, d - 1);
if (loc < (power * 3)) {
if (current->leftChild = nullptr) {
*current->leftChild = newNode;
newNode.parent = current;
next_loc += 1;
break;
}
else {
current = current->leftChild;
}
}
else {
if (current->rightChild = nullptr) {
*current->rightChild = newNode;
newNode.parent = current;
next_loc = +1;
break;
}
else {
current = current->rightChild;
}
}
// Update location and depth to reflect traversal
loc = std::pow(2, d - 1) + loc % power;
d = d - 1;
}
std::cout << current->data << "\n";
system("PAUSE");
}
void TreeHeap::bubble_up( THeapNode *node ) {
if (node == NULL) {
return;
}
THeapNode *parent = node->parent;
while ( parent->data < node->data ) {
parent = node->parent;
string temp = parent->data;
parent->data = node->data;
node->data = temp;
}
}
void TreeHeap::bubble_down( THeapNode *node ) {
if (node == NULL) {
return;
}
while( node->data < node->rightChild->data || node->data < node->leftChild->data ){
if (node->rightChild->data > node->leftChild->data) {
THeapNode *right = node->rightChild;
string temp = right->data;
right->data = node->data;
node->data = temp;
}
else if (node->rightChild->data < node->leftChild->data) {
THeapNode *left = node->leftChild;
string temp = left->data;
left->data = node->data;
node->data = temp;
}
}
}
THeapNode* TreeHeap::find_node( const int position ){
int loc = position;
int d = floor(log2(position));
int power = std::pow(2, d - 1);
THeapNode *returnValue = root;
while (returnValue != NULL && 1 < position && position < (next_loc - 1)) {
if (loc == 1) {
return returnValue;
}
else if (loc < ( std::pow( 2, d-1 ) * 3)) {
returnValue = returnValue->leftChild;
}
else {
returnValue = returnValue->rightChild;
}
// Update location and depth to reflect traversal
loc = std::pow(2, d - 1) + loc % power;
d = d - 1;
}
std::cout << returnValue->data<<"\n";
return returnValue;
}
bool TreeHeap::Delete() {
if (next_loc = 1) {
return false;
}
int d = floor(log2(next_loc - 1));
THeapNode *current = root;
THeapNode *usedNode = NULL;
int loc = next_loc - 1;
while ( 1 ) {
int d = floor(log2(loc));
int power = std::pow(2, d - 1);
if (loc == 1) {
usedNode = current;
break;
}
else if (loc < (std::pow(2, d - 1) * 3)) {
current = current->leftChild;
}
else {
current = current->rightChild;
}
// Update location and depth to reflect traversal
loc = std::pow(2, d - 1) + loc % power;
d = d - 1;
}
THeapNode *temp = root;
clear_heap(root);
root = usedNode;
delete temp;
bubble_down(root);
return true;
}
Thanks in advance for any help you've got.
Quick inspection reveals errors in your bubble_up and bubble_down functions.
In bubble_up, you have the following:
THeapNode *parent = node->parent;
while ( parent->data < node->data ) {
parent = node->parent;
string temp = parent->data;
parent->data = node->data;
node->data = temp;
}
This is going to fail when a node bubbles all the way to the top, because it doesn't check for the node being at the root. You need to write:
while (parent != NULL && parent->data < node->data)
In bubble_down, you have this code:
while( node->data < node->rightChild->data || node->data < node->leftChild->data ){
if (node->rightChild->data > node->leftChild->data) {
You don't check to see if the rightChild or leftChild are NULL.
More importantly, that looks like an infinite loop to me because you never change the value of node.
Those are just the errors I saw on a quick read through your code. There might be more.
I've been struggling with this last function (list_copy_front). The function is for a linked list, it is supposed to return the value of the head pointer for a new list that contains copies of the first n nodes that the source pointer points to. Also if there is less than n nodes in the source then just copy all. Currently, when I run it as is I get a nasty Segmentation Fault SIGSEGV error. The debugger says the error happens at "Node *cursor = source_ptr-> link; Any help would be greatly appreciated, thank you.
Here is some relevant info,
struct Node
{
typedef int Item;
Item data;
Node *link;
};
void list_tail_attach(Node*& head_ptr, const Node::Item& entry);
Node* list_copy_front(Node* source_ptr, size_t n);
void list_tail_attach(Node*& head_ptr, const Node::Item& entry)
{
Node *last = new Node;
last->data = entry;
last->link = NULL;
if(head_ptr == NULL)
{
head_ptr = last;
}
else
{
Node *temp = new Node;
temp = head_ptr;
while(temp->link != NULL)
{
temp = temp->link;
}
temp->link = last;
}
}
Node* list_copy_front(Node* source_ptr, size_t n)
{
Node *new_head_ptr = new Node;
Node *cursor = source_ptr->link;
size_t i = 0;
for(i = 0; i < n; i++)
{
list_tail_attach(new_head_ptr, cursor->data);
cursor = cursor->link;
}
return new_head_ptr;
}
Here's the Main test for the function
int test4()
{
Node* list = NULL; // an empty list
Node* copy = NULL;
copy = list_copy_front(list, 3);
if(copy != NULL)
{
cout << "list_copy_front function doesn't work for copying empty list\n";
return 0;
}
for(int i = 1; i <= 4; i++)
list_tail_attach(list, i);
// list contains 1, 2, 3, 4
copy = list_copy_front(list, 3);
if(list_length(copy) != 3 || copy->data != 1 || copy->link->data != 2 || copy->link->link->data != 3 )
{
cout << "list_copy_front function doesn't work\n";
return 0;
}
copy->link->data = 100;
if(list->link->data == 100)
{
cout << "list_copy_front function doesn't work.\n";
return 0;
}
list_clear(copy);
copy = list_copy_front(list, 6);
if(list_length(copy) != 4)
{
cout << "list_copy_front function doesn't work\n";
return 0;
}
cout << "list_copy_front passes the test\n";
list_clear(list);
for(int i = 1; i <= 3; i++)
list_head_insert(list, i);
// list contains 3, 2, 1
list_copy(list, copy);
if(list_length(copy) != 3 || copy->data != 3 || copy->link->data != 2 || copy->link->link->data != 1 )
{
cout << "list_copy function doesn't work\n";
return 0;
}
cout << "list_copy function passes the test\n";
return 2;
}
Edit 3
So far here's what I'm working with I appreciate the comments so far it's just not quite working out. Which is probably my fault for not explaining better.
void list_tail_attach(Node*& head_ptr, const Node::Item& entry)
{
Node *last = new Node; // Creates new Node
last->data = entry; // Points last to data
last->link = NULL;
if(last == NULL)
{
return;
}
if(head_ptr == NULL)
{
head_ptr = last;
}
else
{
Node *temp = head_ptr;
while(temp->link != NULL)
{
temp = temp->link;
}
temp->link = last;
}
}
Node* list_copy_front(Node* source_ptr, size_t n)
{
if(source_ptr == NULL)
{
return NULL;
}
Node *new_head_ptr = new Node;
Node *cursor = source_ptr;
size_t i = 0;
while(cursor!= NULL && i < n)
{
list_tail_attach(new_head_ptr, cursor->data);
cursor = cursor->link;
i++;
}
return new_head_ptr;
}
I am not allowed to change the way the function takes it's input so, that's why I left Node *last.
I left list_tail_attach(new_head_ptr, cursor->data) because without it I get an invalid conversion error. However when I run the above code I still receive an SIGSEGV error for while(temp->link != NULL) in list_tail_attach and on list_tail_attach(new_head_ptr, cursor->data); in list_copy_front.
Thank you if you are able to comment further
The first test case
Node* list = NULL; // an empty list
Node* copy = NULL;
copy = list_copy_front(list, 3);
gives Node* source_ptr == NULL and expects your function to handle it gracefully.
The function code soon tries to dereference NULL
Node *cursor = source_ptr->link;
The result is a segfault.
First is list_tail_attach, this function I assumed to be attaching an existing Node into a linked list. If the linked list is null then the Node become the head
void list_tail_attach(Node *& head_ptr, Node *& entry)
{
if (entry == NULL) {
return;
}
if (head_ptr == NULL)
{
head_ptr = entry;
}
else
{
Node *temp = head_ptr;
while (temp->link != NULL)
{
temp = temp->link;
}
temp->link = entry;
}
}
I changed the entry into a reference to a pointer to made it easier.
Ok, now move on to the list_copy_front
Node * list_copy_front(Node* source_ptr, size_t n)
{
if (source_ptr == NULL) {
return NULL;
}
Node * new_head_ptr = new Node;
Node * cursor = source_ptr;
size_t i = 0;
while(cursor != NULL && i < n){
list_tail_attach(new_head_ptr, cursor);
cursor = cursor->link;
i++;
}
return new_head_ptr;
}
You have to guard the source_ptr in case it is null.
To attach a new Node
for (int x = 0; x < 5; x++) {
Node * tmp = new Node();
tmp->data = x;
tmp->link = NULL;
list_tail_attach(list, tmp);
}
My professor helped me out with the correct solution. For anyone who views this in the future...
Node* list_copy_front(Node* source_ptr, size_t n)
{
if(source_ptr == NULL) // Takes care of NULL case
{
return NULL;
}
Node *new_head_ptr = NULL; // Creates new head and ensures NULL
Node *cursor = source_ptr; // Sets temp Node = to source
size_t i = 0; // Initializes temp variable
while(cursor!= NULL && i < n) // Loop that continues while n is bigger than i and it is not NULL
{
list_tail_attach(new_head_ptr, cursor->data);
cursor = cursor->link; // Attaches to new list
i++; // Increases count
}
return new_head_ptr;
}
The line that needed to be changed was
Node * new_head_ptr = new Node;
to
Node * new_head_ptr = NULL;
Here is a small Linked List challenge from my class that we need to define a function
void restoreSorted(intListEntry * &)
where intListEntry is a struct
struct intListEntry {
int i; // The int value we want to store in this entry
intListEntry *next; // Address of the next entry in the list
};
The argument is the head of a linked list of integers that sorted in non-decreasing order except for one entry, which is out of place. The function should restore the list to sorted non-decreasing. For example, given as argument; head --> -12 --> -12 --> 0 --> -1 --> 12 --> 122, up on return from restoreSorted(), the list should be: head --> -12 --> -12 --> -1 --> 0 --> 12 --> 122.
and here is my code:
void restoreSorted(intListEntry * &root) {
intListEntry *conductor = root;
intListEntry *checker;
while (conductor->next != NULL) {
if (conductor->i > conductor->next->i) { //detect which one is out of place
checker = conductor;
intListEntry *checker2 = conductor->next;
int temp;
while (checker->i > checker2->i) {
temp = checker->i; //start of swapping value
checker->i = checker2->i; //until it is in the right order
checker2->i = temp;
checker = checker2;
checker2 = checker2->next;
}
break;
}
conductor = conductor->next;
}
However, there are five test cases, and I only pass one of them. I check it over and over again I still cannot find any bug in my code.
With the help of the those comments, I finally debug my code and make two versions using different approach.
The first one is using my original method - bubble sort:
void restoreSorted( intListEntry * &root ){
int length = 0;
intListEntry *current = root;
intListEntry *prev = NULL;
int t = 0;
while (current != NULL){
length++;
prev = current;
current = current -> next;
}
current = root;
prev = NULL;
for (int i = 0; i < length; i++){
for (int j = 0; j < length-1 ; j++){
if (prev == NULL){
prev = current;
current = current->next;
}
if (current->i < prev->i){
t = prev->i;
prev->i = current->i;
current->i = t;
current = current->next;
} else {
prev = current;
current = current->next;
}
if (current == NULL) break;
}
current = root;
prev = NULL;
}
}
The second one is using insertion method:
void restoreSorted(intListEntry * &root) {
intListEntry *conductor = root;
intListEntry *behind = root;
intListEntry *checker;
if (conductor != NULL || conductor->next != NULL) {
while (conductor->next != NULL) {
if (conductor->i > conductor->next->i) {
checker = conductor;
intListEntry *checker2 = conductor;
if (checker2->next->next == NULL) {
int temp = checker->i;
checker->i = checker2->next->i;
checker2->next->i = temp;
break;
} else {
while (checker->i > checker2->next->i && checker2->next != NULL) {
checker2 = checker2->next;
}
if (checker->i > checker2->i && checker2->next == NULL) {
behind->next = checker->next;
checker2->next = checker;
checker->next = NULL;
} else if (checker->i < checker2->next->i) {
behind->next = checker->next;
conductor = checker2->next;
checker2->next = checker;
checker->next = conductor;
break;
}
}
}
behind = conductor;
conductor = conductor->next;
}
}
}
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
Given a Binary Tree, find the deepest leaf node that is left child of its parent. For example, consider the following tree. The deepest left leaf node is the node with value 9.
1
/ \
2 3
/ / \
4 5 6
\ \
7 8
/ \
9 10
The answer is 9.
I developed the following code for this:
int maxlevel = 0;
Node *newNode(int data)
{
Node *temp = new Node;
temp->val = data;
temp->left = temp->right = NULL;
return temp;
}
Node * root;
Node * maxi = NULL;
int getlevel (Node * treeroot,int level, Node * foo)
{
if (treeroot == NULL)
return -1;
else if (treeroot->val == foo->val)
return level+1;
else
{
int downlevel = getlevel(treeroot->left,level+1,foo);
if (downlevel != -1)
return downlevel;
else
downlevel = getlevel(treeroot->right,level+1,foo);
return downlevel;
}
}
void foo(Node * temp)
{
// Base case
if (temp == NULL)
return;
Node * prev;
if (temp->left != NULL)
{
prev = temp;
foo(temp->left);
}
if (prev->left != NULL)
{
if (temp->left == NULL && temp->right == NULL && prev->left == temp)
{
int ind = getlevel(root,0,temp);
if (ind > maxlevel)
{
maxlevel = ind;
maxi = temp;
}
}
}
foo(temp->right);
return;
}
Here, foo is the actual function which determines the deepest left leaf in a tree. getlevel is a function which gets the level of a node in a tree. newNode is a function which allocates a new node.
When I try giving this input tree, it says the leaf is not present. Is there something wrong with my logic?
Thanks!
I think you could simplify this a little by passing the current level and a flag indicating whether the current node is a left or right child into each call...
Something like this:
int maxLevel = 0;
Node* maxNode = null;
void findDeepestLeftNode(Node* node, int level, bool isLeftChild) {
bool isLeaf = true;
if (node->left != null) {
isLeaf = false;
findDeepestLeftNode(node->left, level + 1, true);
}
if (node->right != null) {
isLeaf = false;
findDeepestLeftNode(node->right, level + 1, false);
}
if (isLeaf && isLeftChild && level > maxLevel) {
maxLevel = level;
maxNode = node;
}
}
Then just call it with:
findDeepestLeftNode(root, 0, false);
Assumes the root is not null.