Error in pointer allocation for a binary search tree - c++

I am trying to create a binary tree using C++ classes and pointers. The tree is being initialized properly. However, when I add nodes to the tree, instead of adding them to the left or right sub-tree, the root node gets overwritten. I tried printing the inorder value to check if the nodes are added correctly or not, but that also prints nothing.
Here is the code for the same.
#include <iostream>
#include <conio.h>
#include <stdlib.h>
#include <cstdio>
using namespace std;
class Node{
private:
Node *left;
Node *right;
public:
int number;
Node(int number){
this->number = number;
this->left = NULL;
this->right = NULL;
}
void set_left_node(Node *node){
this->left = node;
}
void set_right_node(Node *node){
this->right = node;
}
Node* read_left_node(){
return this->left;
}
Node* read_right_node(){
return this->right;
}
};
class Binary_Tree{
public:
Node *root;
Binary_Tree(){
this->root = NULL;
}
Node* read_root(){
return this->root;
}
Node* insert_node(Node *root, Node node){
if(!root){
root = &node;
cout << "Inserted " << node.number << " " << root << endl;
return root;
}
else{
cout << "Root and node values " << root->number << " " << node.number << endl;
if(root->number < node.number){
root->set_right_node(insert_node(root->read_right_node(), node));
}
else{
root->set_left_node(insert_node(root->read_left_node(), node));
}
}
return root;
}
void inorder(Node *root){
if (root != NULL){
inorder(root->read_left_node());
cout<<root->number<<" ";
inorder(root->read_right_node());
}
}
};
int main(){
Binary_Tree bt = Binary_Tree();
bt.root = bt.insert_node(bt.root, Node(34));
bt.root = bt.insert_node(bt.root, Node(17));
bt.root = bt.insert_node(bt.root, Node(56));
cout << "Inorder" << endl;
bt.inorder(bt.root);
return 0;
}
Output:

Related

To print the entire sub tree of a given tree recursively

I know how to print the left and right view of a binary tree, but I want to print the entire left subtree of a given tree recursively. So, below is the code I use, and though I am getting the desired output, I feel this is not the proper approach. Is there any other way to achieve the same result without setting the root node's right child to nullptr?
#include<iostream>
using namespace std;
class node
{
public:
int data;
node *lchild;
node *rchild;
};
node *CreateNode(int data)
{
node *NewNode = new node();
NewNode->data = data;
NewNode->lchild = nullptr;
NewNode->rchild = nullptr;
return NewNode;
}
void printEntireTree(node *root)
{
if (root == nullptr)
return;
else
{
cout << root->data<<endl;
printEntireTree(root->lchild);
printEntireTree(root->rchild);
}
}
int main()
{
node *root = CreateNode(3);
root->lchild = CreateNode(1);
root->rchild = CreateNode(4);
root->lchild->rchild = CreateNode(2);
root->lchild->lchild = CreateNode(7);
root->lchild->lchild->lchild = CreateNode(8);
root->lchild->lchild->rchild = CreateNode(9);
root->rchild->lchild = CreateNode(5);
cout << "to print entire left sub tree" << endl;
node *temp = root->rchild;
root->rchild = nullptr;
printEntireTree(root);
root->rchild = temp;
temp = root->lchild;
cout << "entire right sub tree is" << endl;
root->lchild = nullptr;
printEntireTree(root);
root->lchild = temp;
}
#include<iostream>
using namespace std;
class node
{
public:
int data;
node *lchild;
node *rchild;
};
node *CreateNode(int data)
{
node *NewNode = new node();
NewNode->data = data;
NewNode->lchild = nullptr;
NewNode->rchild = nullptr;
return NewNode;
}
void printEntireTree(node *root, node *ro2)
{
if(root== ro2->lchild || root== ro2->rchild)
{
cout << ro2->data<<endl;
}
if (root == nullptr)
return;
else
{
cout << root->data<<endl;
printEntireTree(root->lchild, ro2);
printEntireTree(root->rchild, ro2);
}
}
int main()
{
node *root = CreateNode(3);
root->lchild = CreateNode(1);
root->rchild = CreateNode(4);
root->lchild->rchild = CreateNode(2);
root->lchild->lchild = CreateNode(7);
root->lchild->lchild->lchild = CreateNode(8);
root->lchild->lchild->rchild = CreateNode(9);
root->rchild->lchild = CreateNode(5);
cout << "to print entire left sub tree" << endl;
printEntireTree(root->lchild, root);
cout << "entire right sub tree is" << endl;
printEntireTree(root->rchild, root);
}

How to get below linked list with friend operator to working?

I am trying to execute linked list with the below code.But I am unable to figure out the mistake in it.
I got the concept of it but I am failing to implement the same.
Any help is highly appreciated.
#include <iostream>
using namespace std;
struct Node {
int data;
Node *next;
Node(int j) : data(j), next(nullptr) {}
friend ostream &operator<<(ostream &os, const Node &n) {
cout << "Node\n"
<< "\tdata: " << n.data << "\n";
return os;
}
};
void addElement(Node **head, int data){
Node *temp = nullptr;
temp->data = data;
temp->next=nullptr;
Node *cur = *head;
while(cur) {
if(cur->next == nullptr) {
cur->next = temp;
return;
}
cur = cur->next;
}
};
void printList(const Node *head){
const Node *list = head;
while(list) {
cout << list;
list = list->next;
}
cout << endl;
cout << endl;
};
void deleteList(Node *head){
Node *delNode =nullptr;
while(head) {
delNode = head;
head = delNode->next;
delete delNode;
}};
int main() {
Node *list = nullptr;
addElement(&list, 1);
addElement(&list, 2);
printList(list);
deleteList(list);
return 0;
}
after compiling I am getting no error and no output.So I am unable to figure what is going wrong or else my implementation of which is not right!
Here an error straightaway
void addElement(Node **head, int data){
Node *temp = nullptr;
temp->data = data;
temp is null, but you dereference it. It's an error to dereference a null pointer.
I guess you meant this
void addElement(Node **head, int data) {
Node *temp = new Node(data);
which allocates a new Node, initialises it with data and makes temp point to the newly allocated Node.

binary tree segment fault in C++

I'm trying to code a binary tree search/insert/print(BFS) functions.
It compiles fine, but I keep getting segment faults when I try to insert new nodes. Consequently, I could not test the print function neither. Any suggestions, lads?
I did code the functions in a separate Binarytree.cpp file, by the way.
#ifndef BINARYTREE_H
#define BINARYTREE_H
#include <iostream>
#include <vector>
using namespace std;
typedef struct Node{
int key;
struct Node* leftNode;
struct Node* rightNode;
//C++에서는 struct의 constructor 가능
Node(int _key){key = _key;};
} Node;
class BinaryTree
{
private:
static Node* rootNode;
public:
static Node* search(int searchkey){
Node* curNode = rootNode;
while (curNode){
if (searchkey == curNode->key){
break;
} else if (searchkey < curNode->key){
curNode = curNode->leftNode;
} else {
curNode = curNode->rightNode;
}
}
return curNode;
}
static bool insert(int insertkey){
Node* curNode = search(insertkey);
if (insertkey == search(insertkey)->key){
cout << "Key already exits" << endl;
return false;
}
if (!rootNode){
rootNode = new Node(insertkey);
return true;
} else {
Node* newNode = new Node(insertkey);
newNode = search(insertkey);
return true;
}
}
static void print(){
//Node* rootNode = getRoot();
vector<Node*> v;
if (rootNode == NULL){
cout << "Binary tree is empty." << endl;
return;
} else {
v.push_back(rootNode);
cout << rootNode->key << endl;
}
while (!v.empty()){
Node* temp = v.front();
v.erase(v.begin());
if (temp->leftNode){
v.push_back(temp->leftNode);
cout << temp->leftNode->key << endl;
}
if (temp->rightNode){
v.push_back(temp->rightNode);
cout << temp->rightNode->key << endl;
}
}
}
};
Node* BinaryTree::rootNode = NULL;
#endif
Here in insert:
Node* curNode = search(insertkey);
When you call insert the first time, curNode will be NULL. In the following condition:
if (insertkey == search(insertkey)->key){
cout << "Key already exits" << endl;
return false;
}
you are trying to deference a NULL pointer by doing search(insertkey)->key. This causes the seg fault.
Here is the output from backtrace in gdb on my machine:
Program received signal SIGSEGV, Segmentation fault.
0x00000000004009a3 in BinaryTree::insert (insertkey=1) at binarytree.h:38
38 if (insertkey == search(insertkey)->key){
(gdb) backtrace
#0 0x00000000004009a3 in BinaryTree::insert (insertkey=1) at binarytree.h:38
A quick way you can fix this is check if the return from search is NULL first, then move on to other cases.

Binary tree class implematation

I have the following code. It creates a binary tree class. The functions are insert(), pre_order(), post_order(), in_order(). But when I debug it I get zeros values. Also I insert 9 values but only have 7 zeros. Why I did wrong?
#include <iostream>
using namespace std;
//Begin the construction of the BINARY TREE
struct tree_node {
tree_node *left;
tree_node *right;
int data;
};
//Declaring the class
class bst {
tree_node *root; //creating the root of the binary tree
public:
bst() {
root = NULL; //intialize the default construction, set the root to NULL
}
int is_empty() { //check for empty graph
return (root == NULL);
}
//Manipulating the Binary Tree
void insert(int item);
void remove_it(int value); //difficult implementation
//Graph Traversal of Binary Tree
void in_order_trav();
void in_order(tree_node *);
void pre_order_trav();
void pre_order(tree_node *);
void post_order_trav();
void post_order(tree_node *);
};
void bst::insert(int item) {
tree_node *p = new tree_node;
tree_node *parent;
p->left = NULL;
p->right = NULL;
parent = NULL;
if (is_empty()) {
root = p;
}
else {
tree_node *ptr;
ptr = root;
while (ptr != NULL) {
parent = ptr;
if (item > ptr->data)
ptr = ptr->right;
else
ptr = ptr->left;
}
if (item < parent->data)
parent->left = p;
else
parent->right = p;
}
}
/*************In Order Traversal*****************************/
// Begin
void bst::in_order_trav() {
in_order(root);
}
void bst::in_order(tree_node *ptr) {
if (ptr!=NULL) {
in_order(ptr->left);
cout << " " << ptr->data << " ";
in_order(ptr->right);
}
}
// End
/***********************************************************/
/*************Pre Order Traversal*****************************/
// Begin
void bst::pre_order_trav() {
pre_order(root);
}
void bst::pre_order(tree_node *ptr) {
if (ptr!=NULL) {
cout << " " << ptr->data << " ";
pre_order(ptr->left);
pre_order(ptr->right);
}
}
// End
/***********************************************************/
/*************Post Order Traversal*****************************/
// Begin
void bst::post_order_trav() {
post_order(root);
}
void bst::post_order(tree_node *ptr) {
if(ptr!=NULL) {
post_order(ptr->left);
post_order(ptr->right);
cout << " " << ptr->data << " ";
}
}
// End
/***********************************************************/
int main() {
bst bin_tree; //create the Binary Tree
bin_tree.insert(20);
bin_tree.insert(30);
bin_tree.insert(52);
bin_tree.insert(254);
bin_tree.insert(2);
bin_tree.insert(24);
bin_tree.insert(25);
bin_tree.insert(42);
bin_tree.insert(59);
bin_tree.in_order_trav(); //in order traversal
bin_tree.pre_order_trav(); //pre order traversal
bin_tree.post_order_trav(); //post order traversal
}
The node value should be initialized(p->data = item) at function insert() as below
void bst::insert(int item) {
tree_node *p = new tree_node;
tree_node *parent;
p->left = NULL;
p->right = NULL;
p->data = item;
parent = NULL;
... ...
}
Ok the solution is silly! -.-
I forgot to add that line in insert routine!
p->data = item;

Segmentation Fault (core dumped) when trying to run Queue program - C++

I keep getting a Segmentation fault (core dumped) error every time I try to run my code with g++ on Linux. It compiles fine, but then that happens ... All the functions (remove, add and print) seem to have the same problem, I can't seem to figure out what's wrong... Please heeeelppp.
#include <iostream>
#include <string>
using namespace std;
//Create a node struct
struct Node {
int data;
Node *next;
Node *prev;
};
class Queue {
private:
Node *head;
Node *tail;
int size;
public:
Queue();
~Queue();
void add(int d);
int remove();
bool isEmpty();
void printQueue(bool o);
};
//set to NULL
Queue::Queue() {
head = tail = NULL;
size = 0;
}
//destructor
//call remove until empty
Queue::~Queue() {
while (!isEmpty())
remove();
}
//adds a node with the given data at the back of the queue
void Queue::add(int d) {
Node *temp = new Node();
temp->data = d;
temp->next = NULL;
if (isEmpty()) {
//add to head
head = temp;
} else {
//append
tail->next = temp;
tail = temp;
cout << "Added: " << tail->data << endl;
}
size++;
}
//removes the node at the head of the queue and returns its data
int Queue::remove() {
if (isEmpty()) {
cout << "The queue is empty." << endl;
} else {
Node *temp = new Node;
temp = head;
int value = head->data;
//moves pointer to next node
head = head->next;
cout << "Removed: " << head->data << endl;
size--;
delete temp;
return value;
}
}
//determines if the queue is empty
bool Queue::isEmpty() {
return (size == 0);
}
//prints the contents of the queue from front to back, or front
//to back, depending on the value of the parameter
void Queue::printQueue(bool o) {
if (isEmpty()) {
cout << "The queue is empty." << endl;
} else {
Node *p = new Node;
if (o == true) {
cout << "Printing in front to back:" << endl;
//print front to back
while(p != NULL) {
p = head;
cout << p->data << " ";
p = p->next;
}
} else if (o == false) {
cout << "Printing in back to front:" << endl;
//print back to front
while (p != NULL) {
p = tail;
cout << p->data << " ";
p = p->prev;
}
}
}
}
int main() {
Queue q;
q.add(8);
return 0;
}
EDIT: I've made some changes to the code... But I'm still getting the same error. I assume I'm not updating the head and the tail and/or the next and prev nodes correctly... I don't know why it's wrong or what I'm missing, though.
#include <iostream>
#include <string>
using namespace std;
struct Node {
int data;
Node *next;
Node *prev;
};
class Queue {
private:
Node *head;
Node *tail;
int size;
public:
Queue();
~Queue();
void add(int d);
int remove();
bool isEmpty();
void printQueue(bool o);
};
Queue::Queue() {
head = tail = NULL;
size = 0;
}
Queue::~Queue() {
while (!isEmpty())
remove();
}
void Queue::add(int d) {
Node *temp = new Node;
temp->data = d;
temp->next = NULL;
temp->prev = tail;
if (isEmpty()) {
//add to head
head = temp;
} else {
//append
tail->next = temp;
tail = temp;
cout << "Added: " << tail->data << endl;
}
size++;
}
int Queue::remove() {
if (isEmpty()) {
cout << "The queue is empty." << endl;
return 0;
} else {
Node *temp = head;
int value = head->data;
cout << "Removed: " << head->data << endl;
//moves pointer to next node
head = head->next;
head->prev = NULL;
size--;
delete temp;
return value;
}
}
bool Queue::isEmpty() {
return (size == 0);
}
void Queue::printQueue(bool o) {
if (isEmpty()) {
cout << "The queue is empty." << endl;
} else {
Node *p;
if (o == true) {
p = head;
cout << "Printing in front to back:" << endl;
//print front to back
while(p != NULL) {
cout << p->data << " ";
p = p->next;
}
} else if (o == false) {
p = tail;
cout << "Printing in back to front:" << endl;
//print back to front
while (p != NULL) {
cout << p->data << " ";
p = p->prev;
}
}
}
}
int main() {
Queue q;
q.add(9);
q.add(10);
q.add(11);
q.add(12);
q.add(13);
q.add(14);
q.add(15);
q.add(16);
q.remove();
q.remove();
q.printQueue(true);
q.printQueue(false);
return 0;
}
Lots of problems:
You have a double-linked Node but never update its prev member in the add/remove methods.
You are keeping track of both the Queue head/tail but don't properly update them when you add/remove nodes.
Both your forward and reverse loops in printQueue() are wrong and result in an infinite loop for any queue with 2 or more elements. Queue output should be just something like:
Node *p = head;
while (p != NULL)
{
cout << p->data << " ";
p = p->next;
}
Possible null pointer deference in remove() at cout << "Removed: " << head->data << endl; since you've already moved the head pointer by this time. Move the head after the cout.
Memory leak in Queue::remove() at Node *temp = new Node;. Just do Node* temp = head;.
Memory leak in Queue::printQueue() at Node *p = new Node;. You don't need to allocate a node here.
No return value in remove() for an empty queue.
Edit
Don't forget to initialize the tail when adding a node to an empty list:
if (isEmpty()) {
head = temp;
tail = temp;
}
To remove a node from the head of a non-empty list it should be something like:
Node *temp = head;
head = head->next;
if (head) head->prev = NULL;
size--;
delete temp;
if (isEmpty()) tail = NULL;