Root node not in scope of main function, but defined in public class - scope

I've been working on a program to implement a binary search tree, but using recursion, I have to call the root pointer in the main function. I get the error that 'root was not declared in this scope', although I've declared it inside the bstree class in public. I've been having a really hard time for the past couple of days coming back to this problem and searching all over the internet, so some help would really be appreciated. My code is below (i've removed some functions)
#include <iostream>
using namespace std;
struct Node{
int data;
Node* left;
Node* right;
};
class Bstree{
public:
** Node* root = nullptr;
**
Bstree(){
root = new Node();
}
void insert(Node* root, int x){
if (root==nullptr) {
Node* n = new Node;
n->data = x;
n->right = n->left = nullptr;
} else if (x<root->data) {
insert(root->left, x);
} else {
insert(root->right, x);
}
}
void inorder(Node* root){
if (root==NULL) return;
inorder(root->left);
cout << root->data << " ";
inorder(root->right);
}
void postorder(Node* root){
if (root==NULL) return;
postorder(root->left);
postorder(root->right);
cout << root->data << " ";
}
};
int main(){
Bstree BST;
int N; cin >> N;
for (int i=0;i<N;i++){
int x; cin >> x;
BST.insert(root, x);
}
BST.inorder(root);
BST.postorder(root);
}
I tried to make all recursive functions itirative, but itirative traversal functions are way more complicated than recursive. I tried writing *root instead of root when calling the functions, but I got the same error. Isn't root a global variable anyways since I declared it in a public class?

root is a member of the Bstree class, not a variable that is available in main. In main you could access it with BST.root, however, I feel that the main program has no business with that member. It should be the class that deals with those details, while the main program should just rely on the methods and not have to know about the root member.
So, I would suggest defining public methods on your class that do not take a root parameter. The class knows what the root is, so there's no need for the caller to pass it. However, the recursive calls do need that argument, but those recursive functions could be private methods.
Another issue is that your constructor creates a dummy node and assigns it to the root. This is not good. An empty tree has no node, so you should just leave the root to its initial nullptr value.
Here is an update of your code that fixes these problems:
#include <iostream>
using namespace std;
struct Node{
int data;
Node* left;
Node* right;
};
class Bstree{
private:
Node* root = nullptr;
void insert(Node* &root, int x){
if (root==nullptr) {
root = new Node;
root->data = x;
root->right = root->left = nullptr;
} else if (x<root->data) {
insert(root->left, x);
} else {
insert(root->right, x);
}
}
void inorder(Node* root){
if (root==NULL) return;
inorder(root->left);
cout << root->data << " ";
inorder(root->right);
}
void postorder(Node* root){
if (root==NULL) return;
postorder(root->left);
postorder(root->right);
cout << root->data << " ";
}
public:
// Define the public methods without root argument.
void insert(int x){
// But use a recursive private method that does take that argument
// and pass that argument by reference
insert(root, x);
}
void inorder() {
inorder(root);
}
void postorder() {
postorder(root);
}
};
int main(){
Bstree BST;
int N;
cin >> N;
for (int i = 0; i < N; i++) {
int x;
cin >> x;
BST.insert(x);
}
BST.inorder();
cout << "\n";
BST.postorder();
cout << "\n";
}

Related

pthread_create does not work when a pointer to an object is given as an argument

I don't understand why CLion IDE underlines "pthread_create" and "pthread_join" in red and says "No matching function for call to...". I used a similar code without using the pointer to an object passed to the thread as an argument and it worked.
#include <iostream>
#include <pthread.h>
#define NUM_THREADS 4
using namespace std;
class Animal {
private:
float x, y;
public:
Animal(float x, float y) {
this->x = x;
this->y = y;
}
void print() {
cout<< x << "," << y << endl;
}
};
void *function(Animal *p) {
Animal animal = *p;
animal.print();
}
int main() {
pthread_t thread[NUM_THREADS];
Animal dog[] = {Animal(2, 3), Animal(-1, 2), Animal(5, 2), Animal(5, 10)};
for(int i = 0; i<NUM_THREADS; i++) {
pthread_create(&thread[i], NULL, function, &dog[i]);
}
for(int i = 0; i<NUM_THREADS; i++) {
pthread_join(thread[i]);
}
return 0;
}
I changed the argument of the childThread function from Animal to void *
void *childThread(void *p) {
Animal *animal = (Animal *)p;
animal->print();
}
And added a second argument NULL to pthread_join
pthread_join(thread, NULL)
and now it works

A little trouble with creating a single linked list in C++

I am going to create a single linked list and construct a function (Locate()) that returns the address of the element.But in the end, I didn't see the result of this function. I tried it. This function should be run, but the result is different from what I expected.
use vs2019 on WIndows10,a student:)
#include<iostream>
using namespace std;
struct Node { //Node
int data;
Node* link;
Node(int item, Node* l = NULL)
{
data = item;
link = l;
}
Node(Node* l = NULL)
{
data = 0;
link = l;
}
};
class Link :public Node { //Link
private:
Node* first;
public:
Link(Node* l = NULL)
{
first = l;
}
Link(int d, Node* l = NULL)
{
first = new Node(d);
}
Node* Locate(int i);
};
Node* Link::Locate(int i) //Locate()
{
if (i < 0)
{
cerr << "wrong operation when locating" << endl;
exit(1);
}
int count = 0;
Node* current = first;
while (count < i && current->link != NULL)
{
current = current->link;
count++;
}
return current;
}
int main()
{
Link a;
Node* b = new Node(1);
Node* c = new Node(2);
a.link = b;
b->link = c;
cout << a.data << ' ' << b->data << ' '<<c->data<<endl;
cout << a.Locate(1) << endl;
return 0;
}
Will not output the result of this function 'Locate()' being called
Locate() accesses first->link. At that time, first is a null pointer. Whereupon your program exhibits undefined behavior; in practice, it most likely crashes.
When I re-modify the List constructor, its(Locate()) output is normal and the expected result is obtained.
The modified constructors are as follows:
Link()
{
first = new Node;
}
Link(int d)
{
first = new Node(d);
}
Node* Locate(int i);

I'm not Sure why the incompatible intializer is not compatible with the parameter type int

Basically, I want to display my test scores and the average of them but I am unable to because of these errors
I've tried to take void display and put it in the class and declare it in main but that didn't work
#include <iostream>
#include <string>
using namespace std;
class TestScore
{
public:
TestScore() {};
TestScore(int arr[], int SIZE) {};
void testAvg(int arr[], int SIZE);
void displayArray(int arr[], int Size);
};
void TestScore::testAvg(int arr[], int SIZE)
{
int sum = 0;
for (int i = 0; i < SIZE; i++)
{
sum = sum + arr[i];
try
{
if ((arr[i] > 100) || (arr[i] < 0))
{
throw(1);
}
}
catch (int n)
{
cout << "Error" << endl;
}
}
int average = sum / SIZE;
}
void TestScore::displayArray(int arr[], int SIZE)
{
for (int i = 0; i < SIZE; i++)
{
cout << arr[i] << endl;
}
}
void main()
{
const int SIZ = 5;
int Grade[SIZ] = { 89,65,99,100,81 };
TestScore T(int Grade, int SIZ);
T(Grade, SIZ).testAvg(Grade, SIZ);
T(Grade, SIZ).displayArray(Grade, SIZ);
system("pause");
}
I expect it to display the average of my score so basically, I want to have an array of 5 test scores displaying and then the average of them.
TestScore T(int Grade, int SIZ); declares a function named T, taking two parameters of type int. You then call that function, passing a parameter of type int[5] - not an int. Hence the error message.
Further, that function is not implemented anywhere. Frankly, I don't understand what you are trying to do with that function declaration; it makes little sense.

Overloading "*" Operator for custom SmartPointer

I am trying to directly access integer from a pointer class, by overloading * operator, but it seems VC++ 10 is not allowing it. Kindly help:
#include "stdafx.h"
#include <iostream>
#include <conio.h>
using namespace std;
int MAX7 = 10;
struct node{
int value;
node *next;
};
struct node *head = NULL;
struct node *current = NULL;
int count = 0;
class SmartPointer{
public:
SmartPointer(){
}
int push(int i){
if(count == MAX7) return 0;
if(head == NULL){
head = new node();
current = head;
head -> next = NULL;
head -> value = i;
count = 1;
}
else{
struct node *ptr = head;
while(ptr->next != NULL) ptr = ptr->next;
ptr->next = new node;
ptr = ptr->next;
ptr->next = NULL;
ptr->value = i;
count++;
}
return 1;
}
void Display(){
node *ptr = head;
while(ptr != NULL){
cout << ptr->value << "(" << ptr << ")";
if( ptr == current )
cout << "*";
cout << ", ";
ptr = ptr->next;
}
}
int operator *(){
if(current == NULL) return -1;
struct node *ptr = current;
return ptr->value;
}
};
int main(){
SmartPointer *sp;
sp = new SmartPointer();
sp->push(99);
for(int i=100; i<120; i++){
if(sp->push(i))
cout << "\nPushing ("<<i<<"): Successful!";
else
cout << "\nPushing ("<<i<<"): Failed!";
}
cout << "\n";
sp->Display();
int i = *sp;
getch();
return 0;
}
Error#
1>test7.cpp(71): error C2440: 'initializing' : cannot convert from 'SmartPointer' to 'int'
1> No user-defined-conversion operator available that can perform this conversion, or the operator cannot be called
sp is not a smart pointer - it's a plain old dumb pointer to SmartPointer class. *sp uses built-in dereference operator, producing an lvalue of SmartPointer type. It does not call SmartPointer::operator*() - for that, you need to write **sp (two stars).
It's not at all clear why you want to allocate SmartPointer instance on the heap. That's an unusual thing to want to do (also too, you leak it). I'm pretty sure you would be better off with
SmartPointer sp;
sp.push(99);
and so on.
short answer:
int i = **sp;
You should not allocate objects with new. Your code looks like java. In C++, you must delete everything you allocate with new. In C++ you can write:
SmartPointer sp;
sp.push(99);
int i = *sp;

Runnable implementation using packaged_task in c++11

I am trying to create a Runnable interface in c++11 using packaged_task, with child class overriding run() function. I don't know why this code is not compiling. Its giving error related to type argument.
/usr/include/c++/4.8.1/functional:1697:61: error: no type named ‘type’ in ‘class std::result_of()>’
typedef typename result_of<_Callable(_Args...)>::type result_type;
Below is my code snippet. Could someone plz give me some information on this error and whether implementing Runnable this way is a right way to proceed ?
class Runnable {
public:
explicit Runnable() {
task_ = std::packaged_task<int()>(&Runnable::run);
result_ = task_.get_future();
std::cout << "starting task" << std::endl;
}
virtual int run() = 0;
int getResult() {
task_();
return result_.get();
}
virtual ~Runnable() {
std::cout << "~Runnable()" << std::endl;
}
private:
std::future<int> result_;
std::packaged_task<int()> task_;
};
class foo : public Runnable {
int fib(int n) {
if (n < 3) return 1;
else return fib(n-1) + fib(n-2);
}
public:
explicit foo(int n) : n_(n) {}
int run() {
cout << "in foo run() " << endl;
int res = fib(n_);
cout << "done foo run(), res = " << res << endl;
return res;
}
~foo() {}
private:
int n_;
};
int main(int argc, char*argv[]) {
stringstream oss;
oss << argv[1];
int n;
oss >> n;
shared_ptr<foo> obj(new foo(n));
obj->run();
cout << "done main" << endl;
return 0;
}

Resources