I'm trying to add data to a binary tree, however when I run a method that prints the data of the binarytree in order, nothing prints, and the program exits when it should be printing. I've tested it to see if data is actually being added by having the name and weight values of the rootNode print themselves inside the add method everytime its called, but I cannot get the same results inside of the inOrder method. I believe my issue has something to do with the node being passed.
#include <iostream>
using namespace std;
struct node {
int weight;
string name;
node *left, *right;
};
struct node* newNode(int dataw, string datan)
{
struct node* node = (struct node*)malloc(sizeof(struct node));
node->weight = dataw;
node->name = datan;
node->left = NULL;
node->right = NULL;
return (node);
}
void add(node *rootNode, int dataw, string datan)
{
int lowest_weight;
if (rootNode == NULL )
{
rootNode = newNode(dataw,datan);
lowest_weight = dataw;
}
else
{
if (datan < rootNode->name)
{
if (rootNode->left == NULL)
{
rootNode->left = newNode(dataw,datan);
}
else
{
add(rootNode->left,dataw,datan);
}
}
else
{
if (rootNode->right == NULL)
{
rootNode->right = newNode(dataw,datan);
}
else
{
add(rootNode->right, dataw, datan);
}
}
}
}
void inOrder(node *next)
{
if (next!=NULL)
{
inOrder(next->left);
cout << next->name << " " << next->weight << endl;
inOrder(next->right);
}
}
int main()
{
node *rootNode = NULL;
int height {}, leaves {}, weight {};
string name;
do
{
cout << "Enter name: ";
cin >> name;
if (name == "-1")
break;
cout << "Enter weight: ";
cin >> weight;
add(rootNode, weight, name);
} while (name!="-1");
inOrder(rootNode);
return 0;
}
Resolved it, had to assign the rootNode declaration to a new node method call so the data is not always NULL
node *rootNode = newNode(weight,name);
Related
I am trying to make a tree data structure with c++. Originally I tested with int data, it was going fine. However, when I try to use a string data type, it keeps showing an unhandled exception. It said read access violation, this was 0x5D. I don't know what is causing the error. The complete same code only changing int to string causes the violation.
Main:
#include <bits/stdc++.h>
#include "Tree.h"
using namespace std;
int main()
{
Tree A;
int choice; bool isCre=0;
cout << "Input choice : ";
while (cin >> choice) {
switch (choice)
{
case 1:
if (!isCre) {
A.create_tree(); isCre = 1;
break;
}
else {
A.add_tree();
break;
}
case 2:
A.delete_tree(); break;
case 3:
A.modify_tree(); break;
case 4:
A.display_tree(); break;
}
cout << "Input choice : ";
}
}
Header file:
#ifndef TREE_H
#define TREE_H
#include <bits/stdc++.h>
using namespace std;
class Tree
{
private:
struct Tre
{
Tre* parent; Tre* right; Tre* left;
string data;
Tre(Tre* parent, string data)
{
this->parent = parent;
this->data = data;
left = right = NULL;
}
};
Tre* root;
Tre* create(Tre*& root, string data)
{
Tre* p;
p = new Tre(NULL, data);
root = p;
return root;
}
void dis(Tre* node)
{
if (node == NULL)
return;
cout << node->data << endl;
dis(node->left);
dis(node->right);
}
Tre* search(Tre* node, string data)
{
if (node == NULL)
return NULL;
if (node != NULL && node->data == data)
return node;
/* then recur on left subtree */
Tre* p = search(node->left, data);
// node found, no need to look further
if (p != NULL && p->data == data) return p;
/* node is not found in left,
so recur on right subtree */
Tre* q = search(node->right, data);
if (q != NULL && q->data == data) return q;
}
Tre* add(Tre* root, string find, string input)
{
Tre* p = root;
p = search(root, find);
if (p->left != NULL)
{
p->right = new Tre(p, input);
//p->left = new Tre(p, input);
}
else if (p->left == NULL)
{
p->left = new Tre(p, input);
//p->right = new Tre(p, input);
}
return root;
}
Tre* del(Tre* root, string data)
{
Tre* p = root, * q;
p = search(root, data);
q = p->parent;
if (q->right != NULL && q->right->data == data)
{
q->right = NULL;
delete p;
}
else if (q->left->data == data)
{
q->left = NULL;
delete p;
}
return root;
}
Tre* modify(Tre* root, string find, string input)
{
Tre* p = root;
p = search(p, find);
p->data = input;
return root;
}
public:
void create_tree();
void display_tree();
void add_tree();
void delete_tree();
void modify_tree();
};
#endif
#endif
Implementation file:
#include "Tree.h"
void Tree::create_tree()
{
string data;
cout << "Input data : "; cin >> data;
create(root, data);
}
void Tree::display_tree()
{
dis(root);
}
void Tree::add_tree()
{
string find, input;
cout << "Parent data : "; cin >> find;
cout << "New data : "; cin >> input;
add(root, find, input);
}
void Tree::delete_tree()
{
string data;
cout << "Delete data : "; cin >> data;
del(root, data);
}
void Tree::modify_tree()
{
string find, input;
cout << "Find data : "; cin >> find;
cout << "New data : "; cin >> input;
modify(root, find, input);
}
I have made a C++ program for a binary tree. But the terminal is not asking the statement for inputting the direction for where the elements are to be placed.
Also when I replace the statement from " node *temp = new node " to "node *temp=NULL" the program stops working .
#include <iostream>
#include <cstring>
using namespace std;
class node {
int data;
node * left;
node * right;
public:
node * level_order(node * first);
node * create_bt(node * first);
void display(node * first);
};
//node *first=NULL;
node * node::create_bt(node * first) {
node * temp = new node;
int ele;
//char dir;
cout << "\n Enter data ";
cin >> ele;
temp->data = ele;
temp->left = NULL;
temp->right = NULL;
if (first == NULL) {
temp = first;
return first;
} else {
char dir[20];
cout << "\n Enter the direction ";
cin >> dir;
node * cur = first;
int j = 0;
while (dir[j] != '\0') {
if (dir[j] == 'l') {
cur = cur->left;
}
if (dir[j] == 'r') {
cur = cur->right;
}
j++;
}
cur = temp;
return first;
}
}
void node::display(node * first) {
if (first == NULL)
return;
cout << "\n " << first->data;
display(first->left);
display(first->right);
}
int main() {
int n;
node s;
node * first = NULL;
cout << "\n No of elements ";
cin >> n;
for (int i = 0; i < n; i++) {
first = s.create_bt(first);
}
s.display(first);
return 0;
}
first=s.create_bt(first); does not changes state, from NULL to 'l' or 'r'. You have to change that.
node*node::create_bt(node *first)
{
node *temp=new node;
int ele;
//char dir;
cout<<"\n Enter data ";
cin>>ele;
temp->data=ele;
temp->left=NULL;
temp->right=NULL;
char dir[20];
cout<<"\n Enter the direction ";
cin>>dir;
if(first==NULL)
{
temp=first;
return first;
}
else
{
node*cur=first;
int j=0;
while(dir[j]!='\0')
{
if(dir[j]=='l')
{
cur=cur->left;
}
if(dir[j]=='r')
{
cur=cur->right;
}
j++;
}
cur=temp;
return first;
}
}
I believe you re looking something like this. This is a basic binary tree, i had to make a basic one in order to understand how it works and how it chooses left and right. I make a class inside a class, in order to have access to my data members (node class, int data, *left , *right) and have them at the same time protected, all-in-one. As you can see "newnode" just creates a node and NULL s the pointers. Thats it. "Find" searches and finds a node with a current key, and returns it when exits. All the rest, i guess, you can understand them, as they are prety much the same with your code. The only thing you have to do is to define, when you want to direct the node you want. REMINDER: You have to find a way to utilize it, so the leafs will not end far-left or far-right.("Enter the direction"). I hope i helped you understand.
#include <iostream>
#include <conio.h>
using namespace std;
class mybTree {
class node {
public:
int data;
node * left;
node *right;
};
node *root;
node *newnode(int num){
node *newnode1;
newnode1 = new (nothrow) node;
newnode1->data = num;
newnode1->left = NULL;
newnode1->right = NULL;
return newnode1;
}
public:
node *find (int key) {
node *current;
current = root;
while (current->data !=key){
if (key<current->data){
current = current->left;
} else {
current = current->right;
}
if (current == NULL){
return NULL;
}
}
return NULL;
}
void display (node *ptr);
void display_tree();
bool insert(int num);
void post_order_delete(node *ptr);
mybTree();
~mybTree();
};
int main(){
char ch = ' ';
int a;
mybTree mybTree1;
while (ch !='0'){
cout << "0->Exit"<<endl<< "1-> add"<<endl<< "2-> find" <<endl<<"3-> Show me the tree\n";
ch = getch();
switch (ch) {
case '0':
break;
case '1':
cout << "number";
cin >> a;
if (!mybTree1.insert(a)){
cout << "Not enough memory" << endl;
}
break;
case '2' :
cout << "Number:" ;
cin >> a;
if (mybTree1.find(a)!=NULL) {
cout << "Found" << endl;
} else {
cout << "Not existed" << endl;
}
break;
case '3':
mybTree1.display_tree();
cout<<endl;
break;
default:
cout << "Wrong Message";
break;
}
}
return 0;
}
void mybTree::display(node *ptr) {
if (ptr == NULL){
return;
}
display(ptr->left);
cout << ptr->data<<endl;
display(ptr->right);
}
void mybTree::display_tree() {
//Displays the Tree
display(root);
}
bool mybTree::insert(int num) {
//It inserts a node. Desides left or right.
node *next,*current,*ptr;
int isleft;
next = current = root;
ptr = newnode(num);
if (ptr == NULL) {
return false;
}
if (root == NULL) {
root = ptr;
return true;
}
while (1){
if (num < current->data){
next = current->left;
isleft = 1;
} else {
next = current->right;
isleft = 0;
}
if (next == NULL){
if (isleft){
current->left = ptr;
} else {
current->right = ptr;
}
return true;
}
current=next;
}
return false;
}
void mybTree::post_order_delete(node *ptr) {
//deletes the node. Usefull for destructor
if (ptr == NULL){
return;
}
post_order_delete(ptr->left);
post_order_delete(ptr->right);
cout << ptr->data;
delete ptr;
}
mybTree::mybTree() {
//Constructor
root = NULL;
}
mybTree::~mybTree() {
//Destructor
post_order_delete(root);
root = NULL;
}
When trying to add a new Node to the liked list it gives me a Segmentation fault. Can someone tell me what is wrong in the implementation of the addBook() function. I am not sure if it's the implementation of the function that is wrong, or the way that I've declared the classes.
class Reservation {
public:
int getID();
string getResevNum();
void setId(int x);
void setReseNum(string y);
private:
int ID;
string reservedNumber;
};
class ReservationCollection {
public:
ReservationCollection();
~ReservationCollection();
int getUserId(int &id);
string getUserBook(string &bookCall);
void findReservation();
void display();
void addBook(int id, string book);
void RemoveBook();
void ShutDown();
private:
struct Node {
Reservation *data;
Node *next;
};
Node *head;
};
ReservationCollection::ReservationCollection() {
Node *head = new Node;
head->next = NULL;
}
ReservationCollection::~ReservationCollection() {
}
void ReservationCollection::addBook(int id, string book){
Node *tmp = new Node;
tmp->data->setId(id);
tmp->data->setReseNum(book);
tmp->next = head->next;
head->next = tmp;
cout <<"Good\n";
}
int Reservation::getID(){
return ID;
}
string Reservation::getResevNum(){
return reservedNumber;
}
void Reservation::setId(int x){
ID = x;
}
void Reservation::setReseNum(string y){
reservedNumber = y;
}
int ReservationCollection::getUserId(int &id){
cout << "Enter Id number " << endl;
cin >> id;
return id;
}
string ReservationCollection::getUserBook(string &bookCall){
cout << "Enter book reservatin " << endl;
cin >> bookCall;
return bookCall;
}
int main()
{
int ID;
string BookNum;
char cmd;
do {
cout << "Enter command: ";
cin >> cmd;
ReservationCollection list;
if (cmd == 'A' || cmd == 'a'){
list.getUserId(ID);
list.getUserBook(BookNum);
list.addBook(ID, BookNum);
}
else if (cmd == 'S' || cmd == 's'){
cout << " list";
}
} while (cmd != 'Q' || cmd == 'q');
}
Wish I could just comment this:
All instances of the line Node *tmp = new Node; should read Node *tmp = new Node();
Don't use pointers if you don't have to. In this example Node has to be a pointer, because the list may have zero nodes, or 1000 nodes, so we need pointers to dynamically allocate memory on demand.
But (Reservation)data does not have to be a pointer. Each node always has one Reservation member.
If you do declare it as pointer then you must allocate it, and free it when it is no longer needed.
head should be initialized to NULL, because the single linked-list has no nodes when it is initialized. The first node inserted becomes the head.
#include <iostream>
#include <string>
using namespace std;
class Reservation
{
private:
int ID;
string reservedNumber;
public:
int getID() { return ID; }
string getResevNum() { return reservedNumber; }
void setId(int x) { ID = x; }
void setReseNum(string y) { reservedNumber = y; }
};
class ReservationCollection
{
public:
struct Node
{
Reservation data;
Node *next;
};
ReservationCollection();
~ReservationCollection();
void addBook(int id, string book);
Node* getHead() { return head; }
private:
Node *head;
};
ReservationCollection::ReservationCollection()
{
head = NULL;
}
ReservationCollection::~ReservationCollection()
{
Node *p = head;
while (p)
{
Node *next = p->next;
cout << "delete: " << p->data.getID() << ", " << p->data.getResevNum() << endl;
delete p;
p = next;
}
}
void ReservationCollection::addBook(int id, string book)
{
Node *node = new Node;
node->data.setId(id);
node->data.setReseNum(book);
//this element is the last element
node->next = NULL;
if (!head)
{
//first element inserted
head = node;
head->next = NULL;
}
else
{
//find the previous node in the list
Node *prev = head;
while (prev->next)
prev = prev->next;
//this node is after previous node
prev->next = node;
}
cout << "Good\n";
}
int main()
{
ReservationCollection list;
list.addBook(0, "Book0");
list.addBook(1, "Book1");
list.addBook(2, "Book2");
list.addBook(3, "Book3");
ReservationCollection::Node *p = list.getHead();
while (p)
{
ReservationCollection::Node *next = p->next;
cout << p->data.getID() << ", " << p->data.getResevNum() << endl;
p = next;
}
}
Creating a Node wont create the structure that Reservation *data; tries to point to, and so you try to access non initialized memory.
You need to initialize data:
tmp->data = new Reservation();
I'm trying to make program that reads from a file and adds to a binary tree, but when I try to compile I get an error:
"Error 1 'treePersons::display' : cannot convert parameter 1 from 'Node *' to 'Person *[]'"
The error appears in the call to display() in main()
#include <iostream>
#include <string>
#include <fstream>
using namespace std;
struct Person{
int social;
int birthday;
string first;
string last;
string state;
double balance;
Person();
Person(int s, int b, string f, string l, string t, double a)
{
social = s;
birthday = b;
first = f;
last = l;
state = t;
balance = a;
}
};
struct Node{
Person data;
Node *left;
Node *right;
Node();
Node(Person x){
data = x;
left = NULL;
right = NULL;
}
};
class treePersons
{
protected:
public:
Node *root;
treePersons(){
root = NULL;
}
int fileName(Person *data[])
{
ifstream fin;
fin.open ("dbfile1.txt");
if (!fin.is_open())
cout << "File not found" << endl;
int i;
for(i = 0; i<100; i++)
while(fin.good())
{
fin >> data[i]->social >> data[i]->birthday >> data[i]->first >> data[i]->last >> data[i]->state >> data[i]->balance;
i++;
}
return i;
}
void add(Person *data[], Node*root)
{
int i = fileName(data);
if(root == NULL)
{
root = new Node();
}
for(int l = 0; l<i; l++)
{
if(data[i]->last == root->data.last)
{
if(data[i]->first != root->data.first)
{
if(data[i]->first < root->data.first)
{
add(data, root->left);
}
else if(data[i]->first > root->data.first)
{
add(data, root->right);
}
else if(data[i]->last == root->data.last && data[i]->first == root ->data.first)
{
cout << "already exists" << endl;
}
else if(data[i]->first < root->data.first)
{
add(data, root->left);
}
else if(data[i]->first > root->data.first)
{
add(data, root->right);
}
}
}
}
}
void printAlphabetically(Node *root)
{
if (root != NULL)
{
printAlphabetically(root->left);
cout << root->data.last << endl;
printAlphabetically(root->right);
}
return;
}
void display(Person *data[],Node *root)
{
add(data,root);
printAlphabetically(root);
};
};
struct State{
string state;
Person data;
State* left;
State * right;
State();
State(Person x)
{
data = x;
left = NULL;
right = NULL;
}
};
class treeState{
protected:
State *root;
public:
treeState()
{
root = NULL;
}
};
void main(){
treePersons T;
T.display(T.root->data,T.root);
}
It's very simple to see what's wrong with your code. You have the following:
treePersons T;
T.display(T.root->data, T.root);
Let's have a look at what a treePersons is:
class treePersons
{
Node *root;
...
};
It contains a single member: a Node. A Node is:
struct Node
{
Person data;
Node *left;
Node *right;
...
};
Your treePersons::display() function has the following signature:
void display(Person *data[], Node *root)
And you are passing a t.root->data (a Person) and t.root (a Node*)
The problem is you are attempting to pass a Person as a Person*[] which just isn't going to happen. There's no way to make that Person into a Person[], and you probably meant to make display take a Person* pointer, which will allow you pass a single Person or a container of Person: void display(Person* data, Node* root);
Of course, doing so will lead you down a big trail of problems as #R Sahu pointed out in the comments (most of your functions take a Person*[]. The solution here is to rethink what you are doing, and as #R Sahu suggests start much smaller and build up your program from there.
Consider also using std::vector when you need containers, and std::unique_ptr or std::shared_ptr where you require pointers (otherwise just use objects!). Also read (really read) the compiler output. It's telling you what the problem is, you just need to read.
So I am trying to improve this code in c++. What this does it creates two classes: Student and Studentlist. Any suggestions on improving the linked list data structure here will be greatly appreciated.
#include <iostream>
using namespace std;
//declaring a class student
class Student
{
public:
char *RollNo;
Student *next;
//function student that includes arguments roll number and a pointer poniting to next node student
Student(char *rollNo, Student *Next)
{
this->RollNo = rollNo;
this->next = Next;
}
//fucntion to get roll number
char* getRollNo()
{
return RollNo;
}
//function to get the pointer to next node named student
Student *getNext()
{
return next;
}
void setNext(Student *aNode)
{
this->next = aNode;
}
};
//declareing a class StudentList
class StudentList
{
public:
Student *head;
// default constructor
StudentList()
{
head = NULL;
}
void Add(char *aRollNo)
{
Student *newStudent = new Student(aRollNo, NULL);
Student *temp = head;
if (temp != NULL)
{
while (temp->getNext() != NULL)
{
temp = temp->getNext();
}
temp->setNext(newStudent);
}
else
{
head = newStudent;
}
}
void display()
{
Student *temp = head;
if (temp == NULL)
{
cout << "no student data in the Student List" << endl;
return;
}
if (temp->getNext() == NULL)
{
cout << temp->getRollNo();
}
else
{
do
{
cout << temp->getRollNo() << " --next--> ";
temp = temp->getNext();
} while (temp != NULL);
cout << " end --> null" << endl;
}
}
};
main()
{
StudentList list;
list.Add("My Roll Number is 411\n");
list.display();
cout << "--------------------------------\n";
system("pause");
return 0;
}
The declaration of main() is not complete.
main()
See What is the proper declaration of main?
Also literal strings have a type of char const*. So your method call Add("XXX") has no matching point in the class. The closest you have is Add(char*) which does not match the const part.
Personally I would avoid using C-Strings in C++. You should look at using std::string to handle strings of characters it will avoid many problems.
while you are always add at the last i recomended you to replace your Add algorithm code with this
Student* Add(char *aRollNo,Student* last)
{
Student *newStudent = new Student(aRollNo, NULL);
Student *temp = last;
if (head == NULL){
head=newStudent;
temp=head;}
else
temp=temp->setNext(newStudent);
return temp;
}