This is my first time working with any kind of tree. I created a tnode class for my tree and now I'm trying to create the class for the tree itself. However I've gotten a couple errors I can't figure out.
#ifndef Tree_Ntree_h
#define Tree_Ntree_h
// SIZE reprsents the max number of children a node can have
#define SIZE 10
// SEPERATE will allow the program to distinguish when a subtree no longer has children
#define SEPERATOR '#'
#include <iostream>
#include <fstream>
template <typename T>
class tnode{
public:
T value;
tnode *child[SIZE];
tnode() {};
tnode<T> *addChild(T data){
tnode*temp = new tnode;
temp -> value = data;
for (int i=0; i<SIZE; i++)
temp -> child[i] = NULL;
return temp;
}
};
template <typename T>
class Ntree{
private:
tnode<T> *root;
T data;
std::string filename;
public:
Ntree(){ root= NULL;}
Ntree( T data){ *root = data;}
inline T getRoot(){return root;}
My errors are in the last three lines.
In the last line of my code (getRoot), this is the error:
No viable conversion from 'tnode > *' to
'std::__1::basic_string'
In the second to last line and the third to last line (*root = data) (root = NULL) this is the error:
No viable overloaded '='
I don't understand why it is necessary to overload the = operator in this situation.
root is a tnode<T> * and getRoot is returning a T object. The compiler doesn't know how to convert one to the other. You probably just want to return root->value
However, you haven't allocated any space for root and it might be NULL, so you need to determine what to do when it is NULL.
In this line:
Ntree( T data){ *root = data;}
This time you are assigning a T to a tnode<T>, which the compiler doesn't know how to do. You also haven't allocated any memory for root. Instead you probably want todo something like:
Ntree( T data){ root = new T; root->value = data;}
Or better still have a tnode constructor that takes a value.
Related
Hi I am trying to create a function that counts the number of nodes in the binary tree. I am getting an error that says mismatch of functions. I have gotten other errors and can't seem to get it to work. I know the idea just am having a hard time figuring this one out. Thank You! Edit - My error is mismatch of parameter list.
template<class T>
class BinaryTree
{
private:
struct TreeNode
{
T value;
TreeNode *left;
TreeNode *right;
};
TreeNode *root;
void insert(TreeNode *&, TreeNode *&);
void NodeNumber(TreeNode *&, int&); //My NodeNumber declaration
public:
BinaryTree()
{
root = nullptr;
}
void insertNode(T);
int NodeNum();
};
template <class T>
void BinaryTree<T>::insertNode(T item)
{
TreeNode *newNode = nullptr;
newNode = new TreeNode;
newNode->value = item;
newNode->left = newNode->right = nullptr;
insert(root, newNode);
}
template <class T>
void BinaryTree<T>::NodeNumber(TreeNode *&root, int&)
{
if (root = nullptr)
return;
else
root->right;
root->left;
count = count + 2;
}
template <class T>
int BinaryTree<T>::NodeNum()
{
int count = 0;
NodeNumber(root,count);
return count;
}
You have numerous mis-designs and errors in this class. I will focus on the outright errors. I don't know which of those mis-designs has been mandated by your professor and which are yours.
BinaryTree<T>::NodeNumber, as it is currently written, will crash every time. To figure out why, think carefully about exactly what this line does:
if (root = nullptr)
How does that line differ from these two?
root = nullptr;
if (root)
Secondly, what do the lines:
root->left;
and:
root->right;
do exactly? Why do you think they do that?
Lastly, when exactly should you be adding to count and why? Where is that true?
You didn't give a name to the 2nd parameter in this function, which I assume should be count.
// original
template <class T>
void BinaryTree<T>::NodeNumber(TreeNode *&root, int&)
{
if (root = nullptr)
return;
else
root->right;
root->left;
count = count + 2;
}
A few comments:
If you have a non-null root pointer, you want to visit both left and right child trees. It looks weird that right is in the "else" case, while left is not. I suggest getting rid of the "else" and just return if root is null, and otherwise process both left and right after the if.
You are not testing if the root pointer is null; you are setting it to null.
There is no reason to pass a reference to the root pointer
Your statements like "root->right" do not do anything. You want to recurse down the left child and recurse down the right child, so need to call NodeNumber again and pass your children as the root of these recursive calls, and also pass "count" down too.
Why do you increment by 2? Each node should only count as 1. (Its children will account for themselves as you recurse down them, so only add one for the node itself.)
I prefer to return the count rather than use an "out" parameter
Therefore, consider something like this:
template <class T>
int BinaryTree<T>::NodeNumber(TreeNode *root)
{
if (root == nullptr)
return 0;
int count = 1;
count += NodeNumber(root->right);
count += NodeNumber(root->left);
return count;
}
And of course, adjust the declaration and calls accordingly.
I'm trying to build a function to insert into a binary search tree, but I'm having a hard time figuring out why it won't work. I understand fundamentally how the function is supposed to work, but based on the template I was given it seems as though I am to avoid creating a BST class but instead rely on the Node class and build the desired functions to work on that. Here's the given template:
#include <iostream>
#include <cstddef>
using std::cout;
using std::endl;
class Node {
int value;
public:
Node* left; // left child
Node* right; // right child
Node* p; // parent
Node(int data) {
value = data;
left = NULL;
right = NULL;
p = NULL;
}
~Node() {
}
int d() {
return value;
}
void print() {
std::cout << value << std::endl;
}
};
function insert(Node *insert_node, Node *tree_root){
//Your code here
}
The issue I'm having is when I implement the following code, where getValue is a simple getter method for Node:
int main(int argc, const char * argv[]) {
Node* root = NULL;
Node* a = new Node(2);
insert(a, root);
}
void insert(Node *insert_node, Node *tree_root){
if (tree_root == NULL)
tree_root = new Node(insert_node->getValue());
The code appears to compile and run without error, but if I run another check on root after this, it returns NULL. Any idea what I'm missing here? Why is it not replacing root with a new node equal to that of insert_node?
I also realize this doesn't appear to be the optimal way to implement a BST, but I am trying to work with the template given to me. Any advice would be appreciated.
As Joachim said your issue relates to difference between passing parameter by reference and by value.
In your code void insert(Node *insert_node, Node *tree_root) you pass Node* tree_root by value. Inside the function you change local copy of this pointer, so outer value is not changed.
To fix it you should pass Node* tree_root by reference. Parameter declaration can be Node*& tree_root (or Node** tree_root). E.g:
void insert(Node* insert_node, Node*& tree_root){
if (tree_root == NULL)
tree_root = new Node(insert_node->getValue());
I'm working on implementing linked list using c++. I created a struct Node inside my LinkedList.h, and try to overload operator in node. But when I compiled, I got this error
Code:
#ifndef LINKEDLIST_H
#define LINKEDLIST_H
class LinkedList{
typedef struct Node{
int data;
Node* next;
} * nodePtr;
//Returns true if the current Node object value is
//less than the parameter Node object value
bool operator < (const Node& node) const {
return this->data < node->data; <--- Unable to resolve identifier data.
};
#endif /* LINKEDLIST_H */
I don't know what I did wrong. Can someone tell me please?!
Thanks!
Although I would do this differently, the problem is that you don't define any place in your class to hold a Node structure. I'm not sure if you were trying for this or not:
class LinkedList{
typedef struct Node{
int data;
Node* next;
} * nodePtr;
Node node; // Added this
//Returns true if the current Node object value is
//less than the parameter Node object value
bool operator < (const Node& node) const {
return this->node.data < node.data;
}
};
It looks like you're trying to access something that doesn't exist. Your LinkedList implementation doesn't have a variable named data.
The simplest fix is to change your operator body:
return this->nodePtr->data < node->data;
However, I would suggest refactoring to have a full separate class for Node; you can put the operator overload in that class.
You pass node as reference so you should use node.data
Remove also the keyword typedef because it makes you only define the type and your list definitively needs a pointer to the first node !
Then you have to update your return to:
return this->nodePtr->data < node.data;
I am making a tree of n children to store directories of computer. Now, concept is simply make a tree (that would not be a BT of course) and each node will have children as well. Consider the code below then I will explain the problem.
First Consider this:
C/users/DeadCoder/Movies/Batman.
Now In my main.cpp I have this all C, users, DeadCoder, Movies, Batman in a vector and then I send two pairs in insert Func. if root==NULL; it would just insert C. Next time C and users would go. It would find C and then insert users occordingly. Let's now see the code .
template <class T>
struct Node;
template <class T>
class tree
{
Node<T> *root;
public:
tree();
~tree();
int insert(T str, T str1);
Node<T> *getRoot();
Node<T> *search(T item, Node<T> *tempPtr);
};
template <class T>
struct Node{
T n;
Node<T> *sibling;
tree<T> children; // SEE my each node has children.
Node(T N){
this->n = N;
this->sibling = NULL;
}
};
// In .cpp FILE;
// Initilaizer
template <class T>
tree<T>::tree() // Constructor Initialization.
{
root=NULL;
}
// Insert Function.
template <class T>
int tree<T>::insert(T push, T find)
{
Node<T> *rPtr = root;
if (rPtr==NULL){
//ROOT is NULL. C needs to be inserted which is in find.
Node<T> *pusPtr = new Node<T>(find);
root = pushPtr;
root->sibling=NULL;
return 0;
}
else if(rPtr!=NULL){
Node<T> *pushPtr = new Node<T>(push);
Node<T> *temp2 = search(find, root);
Node<T> *temp = temp2->children.getRoot(); // say it LINE_40.
if (temp==NULL){
temp = pushPtr;
temp->sibling=NULL;
return 1;
}
// children are already present.
else if(temp!=NULL){
// You don't need to know code for this part.
}
}//if.
}
// Search Function.
template <class T>
Node<T> *tree<T>::search(T data, treeNode<T>* N)
{
if (N->n==data){ // where n represent directory.
return N; // data found.
}//if....
else{
Node<T> *child = N->children.getRoot();
// This is where i get Segmentation fault,
// because child is ==NULL; but you see in LINE_40 I did insert the child for C.
if(child!=NULL){ // say it line 80.
search(data, child);
}//if...
if(child->sibling!=NULL){
search(data, child->sibling);
}
}
}// search....
PROBLEM: C inserted. Users inserted. Now in search function at Line 80, it comes to find the child for C. and it should be Users as I have inserted it in LINE 40. BUT Instead it says child==NULL. I have been debugging for hours and I don't know why it says so. I hope Everybody gets the problem.
Now I really need to know why it is regarding C child to be NULL, It has to be users. Can anyOne see what is the problem???? HELP !!!!
Line 42 does nothing (I mean it has no side effect). It just puts a value in a temporary variable then leaves.
You probably want your temp to be a reference to the root. Something like: Node<T> *&temp =
Are you sure insert method actually inserted these elements?
It might be helpful to implement postconditions so to verify your methods actually fulfill their contract (design by contract).
This way you'll directly get what is wrong and debugging will be fast or unnecessary in some cases, since you'll get log messages saying "this method was supposed to do this but failed doing it", otherwise you'll look for hours where the problems comes from.
I'm making a B inary S earch T ree (BST for short) and I've run into a problem that I can't figure out.
I shall try and reduce the amount of code but it still may require quite a bit I'm afraid.
Nodes:
template <typename Type>
class BSTNode { // Binary Search Tree nodes
private:
int key; // we search by key, no matter what type of data we have
Type data;
BSTNode *left;
BSTNode *right;
public:
BSTNode (int, Type);
bool add (int, Type);
Type search (int);
BSTNode<Type> *remove (int, BSTNode*);
BSTNode<Type> *minNode (int);
};
Root:
template <typename Type>
class BST { // The binary search tree containing nodes
private:
BSTNode<Type> *root; // Has reference to root node
public:
BST ();
bool add (int, Type);
Type search (int);
bool remove (int);
};
I don't know how much code to give since I don't want to exaggerate, if you need more, say so please.
I do both do recursive search and remove
template<typename Type>
BSTNode<Type> *BSTNode<Type>::remove(int removeKey, BSTNode *parent) {
// Here I try to remove nodes
// Depending on the number of children a node has, I remove in different ways
// The error occurs at removing a node with 2 children
// here I look for smallest node greater than current node, replace current node, delete node I replaced WITH
if (this->left != NULL && this->right != NULL){
int *auxKey = &key;
this = this->right->minNode(auxKey); // replace
return this->right->remove(this->key, this); // remove old node
}
}
Here is minNode:
template<typename Type>
Type *BSTNode<Type>::minNode (int oldKey) {
if (this->left == NULL) {
//oldKey = this->key;
return this->data;
} else
return left->minNode();
}
This is where the error occurs:
this = right->minNode(auxKey);
This causes a chain of errors, but I think the main error is:
error: invalid conversion from 'int*' to 'int' [-fpermissive]
I'm guessing it's something simple I've overlooked, but I just can't find it, have been trying for quite some time.
EDIT: Decided for now to simply pass key to minNode() and ignore oldKey and auxKey, modified minNode to return pointer.
New Error, same place
lvalue required as left operand
Your minNode function takes in an int value representing the old key, but you're passing an int* into it in the remove function (specifically, auxKey). Try passing in the value of the old key, not a pointer to it. Alternatively, if you want to update the in parameter to hold the correct value (you seem to be trying to do this), change the parameter to a reference parameter.
Hope this helps!