I'm currently attempting to solve the following problem:
Write a function void TreeNode::levelOrder(int n) with wrapper void Tree::levelOrder() to print a tree level-order using recursion
This is the class header:
#ifndef TREE_H
#define TREE_H
#include <algorithm>
class TreeNode {
private:
int key;
TreeNode *left;
TreeNode *right;
public:
TreeNode(int key);
void insert(int key);
void display(TreeNode *p, int lvl);
void preOrder();
void inOrder();
void postOrder();
int size();
int height();
};
class Tree {
private:
TreeNode *root;
public:
Tree();
Tree(int *a, int n);
void insert(int key);
void preOrder();
void inOrder();
void postOrder();
void display(TreeNode *p);
int size();
int height();
};
void TreeNode::display(TreeNode *p, int lvl){
if (p!=NULL){
if (p->left) display(p->left, lvl + 4);
if (p->right) display(p->right, lvl + 4);
if (lvl) {
std::cout << std::setw(lvl) << ' ';
}
cout << p->key << "\n";
}
}
void Tree::display(TreeNode *p){
if (p!=NULL){
return display(p,0);
}
With these two functions, I am still getting the following error:
"./Tree.h:139:20: error: too many arguments to function call, expected single
argument 'p', have 2 arguments
return display(p,3);
~~~~~~~ ^
./Tree.h:137:1: note: 'display' declared here
void Tree::display(TreeNode *p){ "
I don't understand why the compiler can't recognize to call the function from TreeNode class with 2 arguments. Instead, the compiler is telling me the recursive function should only expect one argument.
I know I'm most likely not understanding the bigger picture here so could anyone try and clear this issue up for me? Thanks alot.
The issue is in this method:
void Tree::display(TreeNode *p){
if (p!=NULL){
return display(p,0);
}
return display(p,0); means return this->display(p,0); and the compiler is right.
What you probably meant is p->display(p, 0);.
As a side note, the display() methods in both classes seem to be static methods (and they don't have any reason to be); they don't use the properties of the object used to invoke them.
In order to be correct OOP, you should rewrite them as follows:
void TreeNode::display(int lvl)
{
if (left) {
left->display(lvl + 4);
}
if (right) {
right->display(lvl + 4);
}
if (lvl) {
std::cout << std::setw(lvl) << ' ';
}
cout << key << "\n";
}
void Tree::display(){
if (root) {
root->display(0);
}
}
Related
Hi so there are actually 2 questions. What does All paths through this function will call itself mean? Also I get a segmation fault at the places I put the errors.I tried debugging but I'm confused why it's not working. If someone could not just do this for me but also help explain what I did wrong that'll help alot.
bool operator<=(const Record& rightObj) const {
return this->k <= rightObj.k;
}
template <typename T>
class LinkedList : public List<T> {
protected:
// represents an element in the linked list
struct Node {
T value;
Node* next;
Node(T v, Node* n = nullptr)
: value(v), next(n) { }
};
// a pointer to the front of the list
Node* head;
private:
// copy the values from the argument linked list to `this`
void copy(const LinkedList<T>&);
// merge sort algorithm
void mergeSort(Node*&);
void split(Node*, Node*&, Node*&);
void merge(Node*&, Node*, Node*);
public:
// default constructor
LinkedList();
// copy constructor
LinkedList(const LinkedList<T>&);
// overloaded assignment operator
LinkedList<T>& operator=(const LinkedList<T>&);
// destructor
virtual ~LinkedList();
// add the argument to the end of the list
virtual void append(const T&) override;
// remove all elements in the list
virtual void clear() override;
// return the element at the given position (argument)
virtual T getElement(int) const override;
// return the current length of the list
virtual int getLength() const override;
// insert the given element (argument 2) at
// the given position (argument 1)
virtual void insert(int, const T&) override;
// determine if the list currently empty
virtual bool isEmpty() const override;
// print the elements in the list starting at the given Node (argument)
void print(Node*) const;
// remove the element at the given position (argument)
virtual void remove(int) override;
// replace the element at the given position (argument 1) with
// the value given (argument 2)
virtual void replace(int, const T&) override;
// sort the elements in the list using the algorithm (argument)
// 4 --> merge sort
virtual void sort(int) override;
};
template <typename T>
void LinkedList<T>::mergeSort(Node*& curr) {
Node* n = curr;
Node* a;
Node* b;
if (n == nullptr || n->next == nullptr) {
return;
} // if
// splits linked list
split(n, a, b);
// recursive calls for sorting
mergeSort(a);
mergeSort(b);
// merging lists
merge(n, a, b);
}
template <typename T>
void LinkedList<T>::merge(Node*& curr, Node* A, Node* B) { //I get "All paths through this function will call itself here"
// Node* result = nullptr;
if (A == nullptr) {
curr = B;
} // if
else if (B == nullptr) {
curr = A;
} // else if
if (A->value <= B->value) { //Thread 1: EXC_BAD_ACCESS (code=1, address=0x0)
// cout << "TEST" << endl;
// result = A;
cout << "TEST" << endl;
merge(curr, A->next, B); // Thread 1: EXC_BAD_ACCESS (code=1, address=0x0)
cout << "TEST" << endl;
} // if
else {
// cout << "TEST" << endl;
// result = B;
merge(curr, A, B->next); // segmenation fault here
} // else
curr = A;
}
Here is a simple c++ class for binary tree. Compiler throws an error:
E0147 declaration is incompatible with "void BinaryTree::getLeftChild(node *n)"
Here node is a struct defined under the private section in the class. I am not sure why it says incompatible declaration.
//------------------------ BinaryTree class-----------------
class BinaryTree
{
public:
BinaryTree();
~BinaryTree();
void createRootNode();
void getChildren();
void getLeftChild(node* n);
void getRightChild(node* n);
private:
typedef struct node
{
node *lchild = nullptr;
int data;
node *rchild = nullptr;
}node;
queue <node*> Q;
node *root;
};
BinaryTree::BinaryTree()
{
createRootNode();
getChildren();
}
void BinaryTree::createRootNode()
{
root = new node();
cout << "Enter value for root node" << endl;
cin >> root->data;
Q.push(root);
}
void BinaryTree::getChildren()
{
while (Q.empty == false)
{
getLeftChild(Q.front());
getRightChild(Q.front());
Q.pop();
}
}
void BinaryTree::getLeftChild(node* n)
{
}
void BinaryTree::getRightChild(node* n)
{
}
Code picture with errors
I got another struct in global scope declared as "node" which created chaos. Secondly, i also need to fix the order of public and private sections.
Here is working code
//------------------------ BinaryTree class-----------------
class BinaryTree
{
private:
typedef struct node
{
node *lchild = nullptr;
int data;
node *rchild = nullptr;
}node;
queue <node*> Q;
node *root;
public:
BinaryTree();
~BinaryTree();
void createRootNode();
void getChildren();
void getLeftChild(node* n);
void getRightChild(node* n);
};
BinaryTree::BinaryTree()
{
createRootNode();
getChildren();
}
void BinaryTree::createRootNode()
{
root = new node();
cout << "Enter value for root node" << endl;
cin >> root->data;
Q.push(root);
}
void BinaryTree::getChildren()
{
while (Q.empty() == false)
{
getLeftChild(Q.front());
getRightChild(Q.front());
Q.pop();
}
}
void BinaryTree::getLeftChild(node* n)
{
}
void BinaryTree::getRightChild(node* n)
{
}
First error, is that you need to forward declare the node.
Second error, is that you are trying to access node which is privately declared inside of BinaryTree.
First answer:
typedef struct node
{
node* lchild = nullptr;
int data;
node* rchild = nullptr;
}node;
class BinaryTree
{
public:
BinaryTree();
~BinaryTree();
void createRootNode();
void getChildren();
void getLeftChild(node* n);
void getRightChild(node* n);
private:
node* root;
};
void BinaryTree::getLeftChild(node* n)
{
}
void BinaryTree::getRightChild(node* n)
{
}
Now code compiles fine.
Or if you want to have the typedef defined as private inside, you need the implementation to be inside the class as well.
Second Answer:
typedef struct node;
class BinaryTree
{
public:
BinaryTree();
~BinaryTree();
void createRootNode();
void getChildren();
void getLeftChild(node* n)
{
}
void getRightChild(node* n)
{
}
private:
typedef struct node
{
node* lchild = nullptr;
int data;
node* rchild = nullptr;
}node;
node* root;
};
I am trying to write code to offload the inorder contents of a Binary Tree into a vector.
IE:
#include <iostream>
#include <vector>
#include "BinaryTree.h"
using namespace std;
int main()
{
BinaryTree tree;
vector <double> v;
// Test iterative insert
cout << "Inserting the numbers 5 8 3 12 9.";
tree.insert(5);
tree.insert(8);
tree.insert(3);
tree.insert(12);
tree.insert(9);
// Test vectorExport()
tree.vectorExport(v);
}
I am getting a whole bunch of errors because I don't think I'm implementing it correctly in the member function. I don't know if I'm using the & symbol in the wrong spot or its not in a place it should be. Anyones help would be appreciated.
This is the error I am getting:
[Error] prototype for 'void BinaryTree::vectorExport(BinaryTree::TreeNode*, std::vector<double>&)' does not match any in class 'BinaryTree'
Here is my class:
#ifndef DOUBLEBINARYTREE_H
#define DOUBLEBINARYTREE_H
#include <iostream>
#include <vector>
using namespace std;
class BinaryTree
{
private:
// The TreeNode class is used to build the tree.
class TreeNode
{
friend class BinaryTree;
double value;
TreeNode *left;
TreeNode *right;
TreeNode(double value1, TreeNode *left1 = NULL,
TreeNode *right1 = NULL)
{
value = value1;
left = left1;
right = right1;
}
};
TreeNode *root; // Pointer to the root of the tree
// Various helper member functions.
void insert(TreeNode *&, double);
bool search(TreeNode *, double);
void destroySubtree(TreeNode *);
void remove(TreeNode *&, double);
void makeDeletion(TreeNode *&);
void vectorExport(TreeNode *, vector<double>);
public:
// These member functions are the public interface.
BinaryTree() // Constructor
{ root = NULL; }
~BinaryTree() // Destructor
{ destroySubtree(root); }
void insert(double num)
{ insert(root, num); }
bool search(double num)
{ search(root, num); }
void remove(double num)
{ remove(root, num);}
void vectorExport(vector<double> & v)
{ vectorExport(root, v); }
};
Here is the actual function:
//*********************************************************
// This function offloads tree contents to a vector *
//*********************************************************
void BinaryTree::vectorExport(TreeNode *tree, vector<double> &v)
{
if (tree)
{
vectorExport(tree->left, vector<double> v);
v.push_back(tree->value);
vectorExport(tree->right, vector <double> v);
}
}
Declare the argument as being passed by reference, e.g.
void vectorExport(TreeNode *, vector<double>&);
not
void vectorExport(TreeNode *, vector<double>);
I would like to save my binary tree to txt file. Here's what I have
qt.h
#ifndef QT_H_INCLUDED
#define QT_H_INCLUDED
#include<iostream>
using namespace std;
template<typename T>
class Node{
T data;
Node<T> *left;
Node<T> *right;
public:
Node(T d) : data(d), left(nullptr), right(nullptr){}
void print(){
cout << data << endl;}
T getData()const {
return data;
}
void setData(const T &value){
data = value;
}
template<typename X> friend class Tree;
template<T> friend ostream& operator<<(ostream &os, Node &n);
};
template<typename T>
ostream& operator<<(ostream &os, Node<T> &n){
os << n->data;
return os;
}
#endif // QT_H_INCLUDED
then tree.h
#ifndef TREE_H_INCLUDED
#define TREE_H_INCLUDED
#include "qt.h"
#include <fstream>
#include <iostream>
namespace std;
template<typename T>
class Tree{
Node<T> *root;
void insertIntoTree(T &d, Node<T> *&r);
void printTree(Node<T> *r);
void deleteTree(Node<T> *&r);
Node<T>* findInTree(T &d, Node<T> *r, Node<T> *&parent);
void deleteLeaf(Node<T> *p, Node<T> *q);
void deleteInBranch(Node<T> *p, Node<T> *g);
void zapisDoSouboru(Node<T> *r);
public:
Tree() : root(nullptr){}
~Tree(){
clean();
}
bool find(T d){
Node<T> *dummy=nullptr;
return findInTree(d, root, dummy);
};
void clean(){
deleteTree(root);}
void insert(T d){
insertIntoTree(d, root);}
void print(){
printTree(root);
}
bool deleteNode(T d);
void zapis(){
zapisDoSouboru(root);
}
}
template<typename T>
void Tree<T>::zapisDoSouboru(Node<T> *r){
fstream f;
f.open("mytext.txt", ios_base::app);
if(r){
f << r;
}
f.close();
zapisDoSouboru(r->left);
zapisDoSouboru(r->right);
}
the idea was to overload operator<< for Node and then use recursion in zapisDoSouboru and save it Node by Node. Unfortunately it does not work.
Does anybody know, where the problem is?
Thank you for helping
EDIT
in
class Tree{
void zapis(ostream& f, Node<T> *r);
public:
void zapisDoSouboru(){
fstream f;
f.open("mytext.txt", ios_base::app);
zapis(f, root);
f.close();
}
}
template<typename T>
void Tree<T>::zapis(ostream& f,Node<T> *r){
if(r){
zapis(f, r->left);
f << r;
zapis(f, r->right);
}
}
I changed the whole recursion, but now it looks like it works, but it doesnt write anything in the file. Isnt the reference to f wrong? The file opens and close, zapis() goes through all nodes.
In the function zapisDoSouboru you need to check if the child nodes are nullptr otherwise it will segfault whenever it reaches the leaf nodes.
Here is the modified version:
template
void Tree<T>::zapisDoSouboru(Node<T> *r){
fstream f;
f.open("mytext.txt", ios_base::app);
if(r){
f << r;
}
f.close();
if(nullptr != r->left) {
zapisDoSouboru(r->left);
}
if(nullptr != r->right) {
zapisDoSouboru(r->right);
}
}
Also the operator you have defined for node it is not being picked up by the compiler.
This is the piece of code of your operator:
template<typename T>
ostream& operator<<(ostream &os, Node<T> &n){
os << n->data;
return os;
}
The variable n it is passed by reference and you are accessing it with -> which expects a pointer. The reason why the code compiles is because when you call f << r you actually call the operator with a Node<T>* so the compiler does not use the template function which expects a Node<T>&. Which means the template function is never instantiated.
I think there is not much need for having the operator overload in this case. You can just simply call r->getData()
Also general things i noticed while looking at the code:
I would try to use unique_ptr
I would try to avoid using friend classes
I would refactor the code to not open and close the file at every recursive call
Let me know if you need any clarifications
I am trying to figure out what I am doing wrong with this printList Function. I am getting the following compiler error:
No operator "<<" matches these operands.
The function is as follows:
void printList(const List& theList)
{
for(Node* i = theList.getFirst(); i != theList.getLast(); ++i)
{
cout << *i << " ";
cout << endl;
}
}
I have the following as well,
#include "List.h"
#include <iostream>
I am thinking my print function is just way off base. Can anyone point me in the right direction?
Here are my classes, I don't have a List::Iterator. What would you suggest?
class List
{
private:
int nodeListTotal;
Node* first;
Node* last;
public:
//Constructor
List();
void push_back(Node*);
void push_front(Node*);
Node* pop_back();
Node* pop_front();
Node* getFirst() const;
Node* getLast() const;
int getListLength() const;
void retrieve(int index, int& dataItem) const;
};
class Node
{
private:
string dataItem;
string dataUnit;
int unitTotal;
Node* next;
public:
//Constructor
Node();
Node(int, string, string);
string getDescription( );
void setDescription(string);
string getQuantityName();
void setQuantityName(string);
int getQuantityNumber();
void setQuantityNumber(int);
Node* getNext( );
void setNext(Node*);
};
You need to overload operator<< for Node type:
std::ostream& operator<<(std:::ostream& os, const Node& node)
{
os << node.getQuantityName() << " " << node.getDescription();
return os;
}
As the error message says
No operator "<<" matches these operands.
you don't have the << operator defined for your class.
In your printList() function, replace cout << *i << " "; with
cout << i->getDescription() << endl;