Why does printing a pointer address trigger a breakpoint? - c++

I am trying to implement a binary tree for learning purposes. When I first got the error I thought maybe I was deleting a node twice. Then I realised that even the print statement is triggering a breakpoint. There is no deletion anywhere else in the entire program so the problem has to be here.
here is BinaryTree.cpp
#include "BinaryTree.h"
#include<iostream>
BinaryTree::BinaryTree(void):root(nullptr){}
BinaryTree::~BinaryTree(void){removeWithChildren(root);}
void BinaryTree::insert(Node *n){
cout<<"\nInserting: "<<(void*)n;
Node *y = nullptr;
Node *x = root;
while(x != nullptr){
y = x;
if(n->key < x->key)
x = x->left;
else
x = x->right;
}
n->parent = y;
if(y == nullptr)
root = n;
else if (n->key < y->key)
y->left = n;
else
y->right = n;
}
void BinaryTree::removeWithChildren(Node *n){
//forgetChild(n);
if(n->left)
removeWithChildren(n->left);
if(n->right)
removeWithChildren(n->right);
cout<<"\nDeleting: "<<(void*)n;
delete n;
}
void BinaryTree::remove(Node *n){
if(n->left == nullptr) {
transplant(n,n->right);
} else if(n->right == nullptr) {
transplant(n,n->left);
} else {
Node *y = minimum(n->right);
if(y->parent != n){
transplant(y,y->right);
y->right = n->right;
y->left = n->left;
}
transplant(n,y);
y->left = n->left;
y->left->parent = y;
}
cout<<"\nDeleting: "<<(void*)n;
delete n;
}
void BinaryTree::transplant(Node *u,Node *v){
if(u->parent == nullptr) root = v;
else if (u == u->parent->left) u->parent->left = v;
else u->parent->right = v;
if(v) v->parent == u->parent;
}
string BinaryTree::prewalk(Node *n){
string output = "";
if(n!=nullptr){
output += prewalk(n->left);
output += prewalk(n->right);
output += to_string(n->key);
}
return output;
}
string BinaryTree::inwalk(Node *n){
string output = "";
if(n!=nullptr){
output += inwalk(n->left);
output += to_string(n->key);
output += inwalk(n->right);
}
return output;
}
Node* BinaryTree::search(Node *sub_tree,int key){
if(sub_tree == nullptr) return nullptr;
if(sub_tree->key == key) return sub_tree;
if(sub_tree->key < key) return search(sub_tree->right,key);
else return search(sub_tree->left,key);
}
Node* BinaryTree::getSuccessor(Node *n){
if(n->right)
return minimum(n->right);
Node *y = n->parent;
while(y){
if(n != y->right) break;
n = y;
y = y -> parent;
}
return y;
}
Node* BinaryTree::minimum(Node *sub_tree){
while(sub_tree->left)
sub_tree = sub_tree ->left;
return sub_tree;
}
Node* BinaryTree::maximum(Node *sub_tree){
while(sub_tree->right)
sub_tree = sub_tree ->right;
return sub_tree;
}
void BinaryTree::forgetChild(Node *n){
if(n->parent){
if(n == n->parent->left) n->parent->left = nullptr;
else n->parent->right = nullptr;
}
}
Here is main.cpp
#include"BinaryTree.h"
#include<iostream>
#include<random>
using namespace std;
int main(){
{
BinaryTree bt;
bt.insert(new Node(5));
bt.insert(new Node(1));
bt.insert(new Node(3));
bt.insert(new Node(4));
bt.insert(new Node(9));
//cout<<bt.inwalk(bt.getRoot())<<endl;
bt.remove(bt.search(bt.getRoot(),3));
//cout<<bt.inwalk(bt.getRoot())<<endl;
}
char x;cin>>x;
return 0;
}
Here is BinaryTree.h
#pragma once
#include<string>
using namespace std;
struct Node{
Node *left,*right,*parent;
int key;
Node():left(nullptr),right(nullptr),parent(nullptr),key(0) {}
Node(int x):left(nullptr),right(nullptr),parent(nullptr),key(x) {}
};
class BinaryTree
{
private:
Node *root;
public:
BinaryTree(void);
~BinaryTree(void);
Node* getRoot() { return root; }
void insert(Node *n);
void removeWithChildren(Node *n);
void remove(Node *n);
string prewalk(Node *n);
string inwalk(Node *n);
Node* search(Node *sub_tree,int key);
Node* minimum(Node *sub_tree);
Node* maximum(Node *sub_tree);
Node* getSuccessor(Node *n);
void forgetChild(Node *n);
void transplant(Node* u,Node*v);
};
The destructor calls the removeWithChildren(Node *n) function and the argument being the root of the tree.
I am calling the remove(Node *n) once. When I do not call it, there is no error. I stepped through and inspected the code, the removeWithChildren function is not trying to delete the node which was deleted by the remove function. Still there is an error.
EDIT: I am on Microsoft Visual Studio 2012 Express edition.
I don't know what kind of breakpoint.
EDIT2: Commenting out forgetChild in removeWithChildren fixes the error for some reason.

You did not post the relevant part of your code, but what you posted leads to the guess that you provided neither a valid copy constructor, nor any prevention of use of the default copy constructor. Then you made the mistake of passing an object by value (when you should have passed by reference) thus invoking the default copy constructor and the destructor and corrupting memory.
When working with classes for which copy construction is difficult and probably unnecessary, make sure the default copy constructor is not reachable.

Related

Binary Search Tree Deletion Problem When creating the Node class with left node first

I am creating a binary search tree in C++ using classes. When I write the left address first as in the example, deletion is not working correctly for random nodes.
Example:
class Node{
public:
int data;
Node* left;
Node* right;
Node(){ data=0; right=left=NULL;};
Node(int x){ data=x; right=left=NULL;};
bool is_leaf(){ return (left==NULL && right==NULL);
}
};
class BST{
private:
Node* root;
Node * _del(int x,Node* n);
void _insert_rec(int x,Node*n);
public:
BST(){ root=NULL; };
void insert_rec(int x);
void print();
void del(int x);
};
void BST::del(int x)
{
root = _del(x,root);
}
Node * BST::_del(int x,Node* n)
{
if(!n)
return NULL;
else
{
if(x<n->data)
n->left = _del(x,n->left);
else if(x>n->data)
n->right = _del(x,n->right);
else
{
if(n->is_leaf())
{
delete n;
return NULL;
}
else
{
if(!n->right)
{
delete n;
return n->left;
}
else if (!n->left)
{
delete n;
return n->right;
}
else
{
int enb = _max_value(n->left);
n->data = enb;
n->left = _del(enb,n->left);
}
}
}
}
return n;
}
void BST::insert_rec(int x)
{
root = _insert_rec(x,root);
}
Node * BST::_insert_rec(int x,Node* r)
{
if(!r)
return new Node(x);
else
{
if(x>r->data)
r->right = _insert_rec(x,r->right);
else
r->left = _insert_rec(x,r->left);
}
return r;
}
int main(int argc, char** argv)
{
BST *bst = new BST();
bst->insert_rec(50);
bst->insert_rec(100);
bst->insert_rec(20);
bst->insert_rec(10);
bst->insert_rec(70);
bst->print();
bst->del(100);
cout<<endl;
bst->print();
return 0;
}
When I try to delete 100 or 50, the code doesn't work.
If I change the Node class as below everything works fine:
class Node{
public:
int data;
Node* right; // Only changed the order of the addresses.
Node* left;
Node(){ data=0; right=left=NULL;};
Node(int x){ data=x; right=left=NULL;};
bool is_leaf(){ return (left==NULL && right==NULL);
}
};
Changed the order of the addresses. But I want to understand the reason behind this situation.
One problem is here
if(!n->right)
{
delete n;
return n->left;
}
You are deleting the pointer n and then dereferencing it. You should use a temporary variable
if(!n->right)
{
Node* tmp = n->left;
delete n;
return tmp;
}
With that change (in two places) it seems to work for me.

g++ -O2 flag giving segmentation fault

The program below is a bst tree which works fine under unoptimized settings but produces a SIGSEGV under special circumstances. Since my debugging skills doesn't extend towards assembly, I can use some input to what is causing this error. Below is the full code so it can be reproduced. There is nothing fancy, a node struct is there to hold node data, a simple insert operation and a method to confirm the height of the tree.
#include <iostream>
#include <cstdlib>
using namespace std;
typedef struct avl_tree_node //node data
{
int data;
int balance{0};
avl_tree_node *left{NULL};
avl_tree_node *right{NULL};
avl_tree_node *parent{NULL};
}node;
class avl
{
private:
node *root;
int get_height(node *head) //calculates the height
{
if (head == NULL)
return -1;
int l_height = get_height(head->left);
int r_height = get_height(head->right);
if (l_height > r_height)
return l_height+1;
return r_height+1;
}
void unbalanced_insert(node *head, int item); //method definition for a simple insert
public:
avl(int data)
{
root->data = data;
root->parent = NULL;
root->left = NULL;
root->right = NULL;
}
int height() //gives the height
{
return get_height(root);
}
void unbalanced_insert(int item) //wrapper
{
unbalanced_insert(root, item);
}
};
void avl::unbalanced_insert(node *head, int item) //inserts node to the tree
{
//cout << "stepped" << endl;
if (item > head->data)
{
if (head->right == NULL)
{
head->right = (node*)malloc(sizeof(node));
head->right->data = item;
head->right->parent = head;
head->right->left = NULL;
head->right->right = NULL;
head->balance = 1;
return;
}
unbalanced_insert(head->right, item);
head->balance++;
return;
}
else
{
if (head->left == NULL)
{
head->left = (node*)malloc(sizeof(node));
head->left->data = item;
head->left->parent= head;
head->left->left = NULL;
head->left->right = NULL;
head->balance = -1;
return;
}
unbalanced_insert(head->left, item);
head->balance--;
return;
}
}
int main()
{
avl a(0);
for (int i = 1; i < 5; i++) //works until i < 4
{
a.unbalanced_insert(i);
}
cout << a.height() << endl;
return 0;
}
Under normal circumstances, I'd be happy that this works with unoptimized flags, but I have to build this with specific flags. One of such is the -O2 flag. The segmentation fault occurs between the avl a(0) object construction and the for loop inside main. The error also seems to be dependent on the boolean check of the for loop. This works fine if i < 4 and executed with: g++ avl.cpp -g -O2 -o program && ./program
One obvious problem, and it occurs on the very first function call in main, i.e. avl a(0):
root->data = data;
The root is uninitialized, thus the behavior is undefined.
I guess when instantiate the object of avl here.
avl a(0);
constructor of class as shown below is called.
avl(int data)
{
root->data = data;
root->parent = NULL;
root->left = NULL;
root->right = NULL;
}
But here I see root pointer is not allocated any memory

Undefined Reference to Base Class Constructor

This is my code for an implementation of a doubly linked list that inherits previous code from a single linked list, I am currently having trouble with a linker error and surfed the web for the past hour looking for an answer to my problem and found nothing so far to help me. This is my last resor can anyone help?
Specifically the error i get when i try to use g++ to link my .o files is:
DoublyList.o:DoublyList.cpp:(.text+0xf): undefined reference to
`LinkedList::LinkedList()'
collect2.exe: error: ld returned 1 exit status
I have found very similar questions asked but none of the answers helped me or at least I do not know how to implement them in my code specifically, any help will be apprectiated.
My LinkedList class
#ifndef LINKEDLIST_H
#define LINKEDLIST_H
using namespace std;
struct node
{
float value;
node *next;
};
class LinkedList
{
private:
node *first;
public:
LinkedList();
virtual void insert(float val);
virtual void del(float val);
virtual void read();
virtual int search(float val);
};
#endif
My LinkedList class definition
#include <iostream>
#include "LinkedList.h"
using namespace std;
LinkedList::LinkedList()
{
this->first = NULL;
}
void LinkedList::insert(float val)
{
if(this->first==NULL or this->first->value >= val)
{
node* a_node = new node();
a_node->value = val;
this->first = a_node;
return;
}
node* n = new node();
n = this->first;
node* new_node = new node();
new_node->value = val;
while(n->next != NULL and n->next->value < new_node->value)
{
n = n->next;
}
new_node->next = n->next;
n->next = new_node;
}
void LinkedList::del(float val)
{
node* n = this->first;
node* prev = new node();
prev = n;//in case if it is the first value
int i = this->search(val);
if(this->first->value == val)
{
this->first = this->first->next;
return;
}
if(i != -1)
{
for(int j = 0; j < i; j++)
{
prev = n;
n = n->next;
}
}
//one last check
if(n->value == val)
{
prev->next = n->next;
}
}
void LinkedList::read()
{
node* n = this->first;
int i = 1;
while(n != NULL)
{
cout << i << ". " << n->value << endl;
n = n->next;
i++;
}
}
int LinkedList::search(float val)
{
int i = 0;
node* n = this->first;
while(n != NULL)
{
if(n->value == val)
return i;
else
{
n = n->next;
i++;
}
}
return -1;
}
My doublylist class
#ifndef DOUBLYLIST_H
#define DOUBLYLIST_H
#include "LinkedList.h"
class DoublyList: public LinkedList
{
public:
struct node
{
float value;
node * next;
node * prev;
};
node * first;
DoublyList();
void insert(float val);
void del(float val);
void read();
int search(float val);
};
#endif
My Doubly List definiton
#include <cstddef>
#include "DoublyList.h"
#include "LinkedList.h"
using namespace std;
//constructor
DoublyList::DoublyList()
{
first = NULL;
}
//Insert a node into the correct position in the doubly linked list
void DoublyList::insert(float val)
{
//if linked list is empty or val <= the first node
if(this->first == NULL or this->first->value >= val)
{
node * a_node = new node();
a_node->value = val;//set node's value
//begin replacing and assigning pointers
a_node->next = this->first;
a_node->prev = NULL;
this->first = a_node;
return;
}
node * n = new node();
n = this->first;
node * new_node = new node();
new_node->value = val;
node * prev_node = new node();
while(n->next != NULL and n->next->value < new_node->value)
{
prev_node = n;
n = n->next;
}
prev_node->next = new_node;
new_node->next = n->next;
new_node->prev = prev_node;
n->next = new_node;
}
void DoublyList::del(float val)
{
node * n = this->first;
int i = this->search(val);
//if first node
if(this->first->value == val)
{
this->first = this->first->next;
this->first->prev = NULL;
return;
}
//if value found
if(i != -1)
{
for(int j = 0; j < i; j++)
{
n = n->next;
}
//if a middle node
if(n->value == val and n->next != NULL)
{
n->prev->next = n->next;
return;
}
//if last node
if(n->prev != NULL)
{
n->prev->next = n->next;
}
}
return;//value not found so return
}
void DoublyList::read() { }
int DoublyList::search(float val) { }
Edit: Forgot to mention this error specifically happens aruond line 8 of DoublyList.cpp, this was from previous trials to link the .o files.
The command I used to call the linker is
g++ -g main2.cpp DoublyList.o
Where main2.cpp is the code that contains my main function to test the code.
Thanks to xskxzr the solution was to also link LinkedList.o along with all the rest of the .o files. If anyone ever has the same problem this is the answer.

C++ Hexadecimal Multiplication Segmentation Fault [closed]

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 6 years ago.
Improve this question
Let me first start by saying I do not have access to debuggers and I'm using Nano as my editor
Currently, with my calculator, I am beating my head against a brick wall(segmentation fault). I've tried going through my pointers to discover what my problem is, but my lack of experience/knowledge has only gotten me so far. Let me explain what works so far in my program. Currently, I am able to store hexadecimal numbers in a linked list and add them together. The problem comes from my multiplication method.Somehow leftNode is becoming NULL midway through the multiplication method throwing a segmentation fault. I'm wondering at what point does leftNode become NULL?
Multiplication Method:
LList Calculator::multiply(LList& left, LList& right) {
LList prodSum;
listnode *leftNode = (left.next());
int zeros = 0;
for(;;) {
if(leftNode == NULL) break;
int lval = leftNode->data;
LList curList;
for(int i = 0; i < zeros; i++) {
curList.insertTail(0);
}
right.reset();
listnode *rightNode = (right.next());
int carry = 0;
while(rightNode != NULL) {
int rval = rightNode->data;
int product = lval * rval + carry;
carry = product / 16;
product %= 16;
curList.insertTail(product);
rightNode = (right.next());
}
while(carry) {
curList.insertTail(carry % 16);
carry /= 16;
}
prodSum = *add(prodSum, curList);
leftNode = (left.next()); // eventually causes a segmentation fault
leftNode->data << endl;
++zeros;
}
return prodSum;
}
Classes related to multiplication:
class listnode {
public:
element data;
listnode * next;
};
class LList {
private:
listnode * head;
listnode * tail;
listnode * view;
public:
LList();
~LList();
void read();
listnode* next();
void reset();
void print();
void insertTail(element val);
void clean();
element deleteHead();
};
class Calculator {
public:
Calculator();
//inline LList* add(LList& left, LList& right); works
inline LList multiply(LList& left, LList& right);
};
Calculator::Calculator() {
};
Other methods related to traversing nodes:
listnode* LList::next() {
listnode* temp = view;
if(temp != NULL)
view = view->next;
if(view == NULL) {
}
return temp;
};
void LList::reset() {
view = head;
}
LList::LList(){
head = NULL;
view = NULL;
};
void LList::insertTail(element val) {
listnode * temp;
temp = new listnode;
temp -> data = val;
temp -> next = NULL;
if(head == NULL) {
head = temp;
view = head;
}
else
tail -> next = temp;
tail = temp;
};
void LList::clean() {
while(head != NULL)
deleteHead();
};
element LList::deleteHead() {
listnode * temp;
temp = head;
head = head -> next;
delete temp;
return temp -> data;
};
LList::~LList(){
delete head;
};
it's me again.
One exception occurs after the line you marked: // eventually causes a segmentation fault, there seems to be a partially-formed line for sending leftNode->data to cout, but on the final iteration through left's nodes, leftNode = (left.next()); will set leftNode to NULL, so a dereference here might be causing the fault.
One other problem is that no copy constructor or assignment operator is defined for LList, so this line: prodSum = *add(prodSum, curList); will give prodSum a set of list nodes that will be deleted right after.
However, LList's destructor only seems to delete the head node, not the whole list, so there's a grab-bag of invalid and valid going on.
Also, multiply returns prodSum, so the lack of a copy constructor will make something similar happen.
I'm including a version of your code that seems to work. I had to make my own add function, just because I don't see it here.
I made the destructor delete all of the LList's nodes.
I marked the default copy constructor and assignment operator =delete because the default implementations do the wrong thing.
In order to pass LList objects around by value, I added a move constructor and a move assignment operator. These pass allocated nodes from one object to another, and only one object is allowed to keep one set of nodes, so you don't have to worry about double-destruction.
#include <iostream>
#include <string>
typedef int element;
class listnode {
public:
element data;
listnode * next;
};
class LList {
listnode *head, *tail, *view;
public:
LList() { head = view = tail = NULL; }
LList(LList&& src) : head(src.head), tail(src.tail), view(src.view) { src.head = src.tail = src.view = nullptr; }
LList(const LList&) = delete;
~LList() { clean(); }
LList& operator = (LList&& src) {
clean();
/* OK here */
head = src.head;
tail = src.tail;
view = src.view;
src.head = src.tail = src.view = nullptr;
return *this;
}
LList& operator = (const LList&) = delete;
listnode* next() {
listnode* temp = view;
if(temp) view = view->next;
return temp;
}
void reset() { view = head; }
void print();
void insertTail(element val) {
listnode* temp = new listnode;
temp->data = val;
temp->next = NULL;
if(!head) { view = head = temp; }
else { tail->next = temp; }
tail = temp;
}
void clean() { while(head) deleteHead(); }
element deleteHead() {
listnode* temp = head;
head = head->next;
const element data = temp->data;
delete temp;
return data;
}
};
LList add(LList& left, LList& right) {
LList sum;
int carry = 0;
left.reset();
right.reset();
for(;;) {
const listnode* leftNode = left.next();
const listnode* rightNode = right.next();
if(!leftNode && !rightNode) break;
if(leftNode) carry += leftNode->data;
if(rightNode) carry += rightNode->data;
sum.insertTail(carry % 16);
carry /= 16;
}
if(carry) sum.insertTail(carry);
return sum;
}
LList multiply(LList& left, LList& right) {
LList prodSum;
listnode *leftNode = left.next();
int zeros = 0;
for(;;) {
if(!leftNode) break;
int lval = leftNode->data;
LList curList;
for(int i = 0; i < zeros; i++) {
curList.insertTail(0);
}
right.reset();
listnode *rightNode = right.next();
int carry = 0;
while(rightNode) {
int rval = rightNode->data;
int product = lval * rval + carry;
carry = product / 16;
product %= 16;
curList.insertTail(product);
rightNode = right.next();
}
while(carry) {
curList.insertTail(carry % 16);
carry /= 16;
}
prodSum = add(prodSum, curList);
leftNode = left.next(); // eventually causes a segmentation fault
//std::cout << leftNode->data << std::endl;
++zeros;
}
return prodSum;
}
LList string_to_list(std::string hex_string) {
LList list;
for(size_t i=hex_string.length()-1; i+1; --i) {
char c = hex_string[i] | 0x20;
if (c >= '0' && c <= '9') list.insertTail(c - '0');
else if(c >= 'a' && c <= 'f') list.insertTail(c - 'a' + 10);
}
return list;
}
std::string list_to_string(LList& list) {
std::string hex_string;
list.reset();
for(;;) {
listnode* node = list.next();
if(!node) return hex_string;
static const char digits[] = "0123456789abcdef";
hex_string = digits[node->data] + hex_string;
}
}
int main() {
//LList list = string_to_list("1234aBcd");
//std::string s = list_to_string(list);
//std::cout << s << '\n';
LList left = string_to_list("111");
LList right = string_to_list("333");
LList prod = multiply(left, right);
std::cout << list_to_string(prod) << '\n';
}

A count function that counts the leaf nodes of a height balanced tree

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