Binary Search Tree Implementation. Problems With Compilation [closed] - c++

Closed. This question is not reproducible or was caused by typos. It is not currently accepting answers.
This question was caused by a typo or a problem that can no longer be reproduced. While similar questions may be on-topic here, this one was resolved in a way less likely to help future readers.
Closed 6 years ago.
Improve this question
Basically, I'm getting problems in both the header file and the cpp file with the search function. It just says "Member declaration not found" and "prototype for 'node *BTree::search(int) does not match any in class BTree". I only listed the search functions in the cpp file to make it easier, because my insert and destroy_tree functions both work fine.
Header file:
#ifndef BTREE_H_
#define BTREE_H_
class BTree {
public:
struct node{
int key_value;
node *left;
node *right;
};
BTree();
virtual ~BTree();
void insert(int key);
node* search(int key);
void destroy_tree();
node *root;
private:
void insert(int key, node *leaf);
node* search(int key, node *leaf);
void destroy_tree(node *leaf);
};
#endif /* BTREE_H_ */
Implementation:
#include "BTree.h"
#include <iostream>
using namespace std;
struct node{
int key_value;
node *left;
node *right;
};
BTree::BTree() {
root = NULL;
}
BTree::~BTree() {
destroy_tree();
}
node BTree::*search(int key, node *leaf){
if(leaf != NULL){
if(key == leaf->key_value){
return leaf;
}
if(key < leaf->key_value){
return search(key, leaf->left);
}
else{
return search(key, leaf->right);
}
}
else return NULL;
}
node *BTree::search(int key){
return search(key, root);
}

You have two struct node structs, one declared globally (in your .cpp file) and one declared within the BTree class. These are two different structures, one named ::node (global), the other BTree::node. In your header file search refers to the one defined within the class, while the function declaration in the .cpp file refers to the global one.
Remove the global struct, and declare the search function using BTree::node *BTree::search instead.

Related

Identifier Node* is undefined(linker problem) [duplicate]

This question already has answers here:
Where and why do I have to put the "template" and "typename" keywords?
(8 answers)
Closed last month.
I am really sorry if this is a duplicate post, but I am really stuck on this particular problem. For some inexplicable reason the compiler does not understand what return type Node* is on the .cpp file, here is the code:
template<typename T>
Node* BinarySearchTree<T>::DiveDownToReplace(Node* node) {
if (node->leftChild->rightChild == nullptr) {
return node->leftChild;
}
//otherwise
Node* traversingNode = node->leftChild;
Node* returnedNode;
while (true) {
if (traversingNode->rightChild->rightChild == nullptr) {
returnedNode = traversingNode->rightChild;
traversingNode->rightChild = returnedNode->leftChild;
returnedNode->leftChild = nullptr;
break;
}
traversingNode = traversingNode->rightChild;
}
return returnedNode;
}
Here is also the code in the .h(header file):
#pragma once
template<typename T>
class BinarySearchTree {
private:
struct Node
{
T data;
Node* leftChild;
Node* rightChild;
};
int m_Length = 0;
Node* root = new Node();
public:
enum class TraverseMethod
{
preorder,
inorder,
postorder,
levelorder
};
~BinarySearchTree();
void AddElement(T value);
T RemoveRoot();
bool RemoveElement(T value);
void PrintAllElements(TraverseMethod traverseMethod);
bool IsEmpty();
bool GetSize();
bool Contains(T value);
private:
void PreOrder(Node* node);
void InOrder(Node* node);
void PostOrder(Node* node);
void LevelOrder(bool deleteNode = false);
void DiveDownToAdd(T value, Node* node);
Node* DiveDownToReplace(Node* node);
};
I am getting the error "identifier Node is undefined". I tried adding BinarySearchTree::Node* instead of Node*, but I received some weird errors(c2061, syntax error: identifier 'Node'). Once more I am sorry if this post is duplicate, but coming from languages like c# and Java I am really fed up with these header issues. Thank you in advance!
There are two rather complicated technical details of C++ that get combined together here. First of all, is scoping and namespaces.
//otherwise
Node* traversingNode = node->leftChild;
This is code that's inside a member function of the BinarySearchTree template. When a symbol, such as Node gets used the compiler needs to know what in blazes is that. BinarySearchTree defines an inner class named Node, so there you go. Problem solved.
template<typename T>
Node* ...
But what the heck is this? What is this weird Node all about? This part of the C++ code is not inside a member function. You better have a global class, or something, named Node, or you'll be in big trouble.
Just because there happens to be some class or template that's defined, and it has an inner class named Node, well this means absolutely nothing, whatsoever. When some symbol name is used, in global scope, the compiler is not going to search every class for something that happens to have the same name. C++ does not work this way.
And that's why you must spell everything out:
template<typename T>
typename BinarySearchTree<T>::Node *
The "template<typename T>" stuff makes a grandiose entrance of a template parameter that's represented by symbol T, and BinarySearchTree<T>::Node spells everything out.
And the second part of this story, the only remaining question here, is what in blazes is that typename all about.
Well, that's a long story, that you can read by yourself.

Declare methods with pointer outside class in C++ [closed]

Closed. This question is not reproducible or was caused by typos. It is not currently accepting answers.
This question was caused by a typo or a problem that can no longer be reproduced. While similar questions may be on-topic here, this one was resolved in a way less likely to help future readers.
Closed 1 year ago.
Improve this question
I want to declare the methods of the following code outside the class but i get the following error whenever the method is a pointer to private member variable:
"no instance of function template "std::next" matches the required typeC/C++(386)".
class Node
{
private:
int data;
Node *next;
public:
Node() {}
int GetData() { return data; }
Node *GetNext() { return next; }
void SetData(int aData) { data = aData; }
void SetNext(Node *aNext) { next = aNext; }
};
// outside try class declaration of
int Node::GetData() { return data; }
Node Node::*GetNext() { return next; } // here is the error!!
Would you help me?
This is wrong
Node Node::*GetNext() { return next; }
This is right
Node* Node::GetNext() { return next; }
The name of function is Node::GetNext and not GetNext.
You must put the asterisk after the return type because the return type is a pointer to Node object
like this:
Node *Node::GetNext() { return next; }
When you write Node *GetNext();, this means the method name is GetNext and the return type is Node *. It doesn't matter whether you put the asterisk near the method name or away from it.
Outside of the class, you need fully qualified name of the method which is Node::GetNext with return type Node *. So it would look like Node *Node::GetNext(); or Node* Node::GetNext(); depending on your style of the placement of the asterisk.

Why can't use '->' c++ template class [closed]

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 4 years ago.
Improve this question
#include <iostream>
using namespace std;
template <typename E>
class NodeList {
public:
class Node {
public:
Node* next;
Node* prev;
E elem;
};
public:
Node* begin() const;
NodeList();
public:
Node* header;
Node* trailer;
int size;
};
template <typename E>
NodeList<E>::NodeList(){
size = 0;
header = new Node;
trailer = new Node;
header->
trailer->
}
I want to use member variables of NodeList class, but can't use it.
such as header->next or trailer-> prev
'->' why?
I wonder why can't use it!
sorry I revised it!
from
header->trailer
to
header->next
when I type '->' then Nothing action like next, prev, elem
Well, header is a property of NodeList and is a pointer to a Node.
A Node doesn't have headers or tailers, it just has prev and next. So you can use header->next and trailer->prev if you want.

error 'TempSLLNODE' : use of class template requires template argument list [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 9 years ago.
Improve this question
#ifndef TEMPLATE_LINKED_LIST
#define TEMPLATE_LINKED_LIST
template <class T>
class TempSLLNODE
{
public:
T info;
TempSLLNODE *next;
TempSLLNODE( T value, TempSLLNODE *ptr = NULL)
{
info = value;
next = ptr;
}
};
template <class T>
class TempSLL
{
public:
TempSLL()
{
head = tail = 0;
}
~TempSLL();
T isEmpty()
{
return head == 0;
}
void addToHead(T);
void addToTail(T);
T deleteFromHead(); // delete the head and return its info;
T deleteFromTail(); // delete the tail and return its info;
void deleteNode(T);
bool isInList(T) const;
private:
TempSLLNODE *head, *tail;
};
#endif
TempSLLNODE is template, you need to use it with type:
update:
TempSLLNODE *head, *tail;
to:
TempSLLNODE<T> *head, *tail;
// ^^^
You could at least mention the line of the error.
For future reference, the error is here:
private:
TempSLLNODE *head, *tail;
You need to know that when you instantiate a variable from a class template, you should mention the template type. In fact, for each template type you use to instantiate a variable, the compiler compiles and generates code of the class for you, and before doing so, compiler does not generate any code for the class template.
So I guess what you meant here is:
private:
TempSLLNODE<T> *head, *tail;

How to declare the nested classes correctly? [closed]

Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
Questions concerning problems with code you've written must describe the specific problem — and include valid code to reproduce it — in the question itself. See SSCCE.org for guidance.
Closed 9 years ago.
Improve this question
Following code is a implemention of Binary Tree, coming from a C++ data structure text.
I canot compile the code successfully, getting some error messages. Mainly, the error lines comes from the last two of the code. How to fix this problem?
My IDE is CODE::BLOCK 12.11.
#include<iostream>
#include<list>
using namespace std;
typedef int Elem;
struct Node
{
Elem elt;
Node *par;
Node *left;
Node *right;
Node():elt(),par(NULL),left(NULL),right(NULL){}
};
class Position
{
private:
Node *v;
public:
Position(Node *_v=NULL):v(_v){}
Elem &operator*(){return v->elt;}
Position left()const{return Position(v->left);}
Position right()const{return Position(v->right);}
Position parent()const{return Position(v->par);}
bool isRoot()const{return v->par==NULL;}
bool isExternal()const{return v->left==NULL&&v->right==NULL;}
friend class LinkedBinaryTree;
};
typedef std::list<Position> PositionList;
class LinkedBinaryTree
{
protected:
struct Node; //This line is by me, the text merely tell you "insert Node declaration here. . ." I don't know whether this line is correct or not.
public:
class Position; // Also by me, the text merely tell you "insert Position declaration here. . ." I don't know wwhether this line is correct or not.
public:
LinkedBinaryTree();
int size()const;
bool empty()const;
Position root()const;
PositionList positions()const;
void addRoot();
void expandeExternal(const Position& p);
protected:
void preorder(Node* v,PositionList& pl)const;
private:
Node* _root;
int n;
};
LinkedBinaryTree::LinkedBinaryTree():_root(NULL),n(0){}
int LinkedBinaryTree::size()const{return n;}
bool LinkedBinaryTree::empty()const{return size()==0;}
LinkedBinaryTree::Position LinkedBinaryTree::root()const{Position(_root);} //canot compile successfully, this error messages is : C:\Users\user\Documents\aa\main.cpp|58|error: return type 'class LinkedBinaryTree::Position' is incomplete
void LinkedBinaryTree::addRoot(){_root=new Node;n=1;} //canoot compile successfully, this error message is C:\Users\user\Documents\aa\main.cpp|59|error: invalid use of incomplete type 'struct LinkedBinaryTree::Node'
There are many error messages, I select one of them to represent the error messages.
This:
class LinkedBinaryTree {
protected:
struct Node;
is called a forward declaration (of Node). It tells the compiler there is a type with that name, but it is not a definition of a class. You cannot create an instance of a type, unless its definition is visible. A forward declaration is not a definition.
If you had written:
class LinkedBinaryTree {
protected:
struct Node { /* ... */ };
Then you would be able to create a Node.
The forward declaration of a nested class is generally useful when you have codependent types, or you prefer to order declarations in a specific way.
The forward declaration is useful to tell the compiler there is a type with that name, so it can understand your intent before it is used:
class LinkedBinaryTree {
protected:
struct Node;
void foo(Node*);
struct Node { /* ... */ };
In this case, a pointer does not require physical dependence, so the name is enough to satisfy the compiler when it sees the declaration of foo.
Also note that your forward declaration declares a Node and Position in the class' scope, so the compiler takes it to mean that void preorder(Node* v,PositionList& pl)const; uses the types local to the class; e.g. void LinkedBinaryTree::preorder(LinkedBinaryTree::Node* v, LinkedBinaryTree::PositionList& pl)const;, rather than the Position and Node declared in the global namespace in your code sample.
Nested declaration should normally happen inside the class, like this:
#include<iostream>
#include<list>
using namespace std;
class LinkedBinaryTree
{
protected:
typedef int Elem;
struct Node
{
Elem elt;
Node *par;
Node *left;
Node *right;
Node():elt(),par(NULL),left(NULL),right(NULL){}
};
public:
class Position
{
private:
Node *v;
public:
Position(Node *_v=NULL):v(_v){}
Elem &operator*(){return v->elt;}
Position left()const{return Position(v->left);}
Position right()const{return Position(v->right);}
Position parent()const{return Position(v->par);}
bool isRoot()const{return v->par==NULL;}
bool isExternal()const{return v->left==NULL&&v->right==NULL;}
friend class LinkedBinaryTree;
};
typedef std::list<Position> PositionList;
public:
LinkedBinaryTree();
int size()const;
bool empty()const;
Position root()const;
PositionList positions()const;
void addRoot();
void expandeExternal(const Position& p);
protected:
void preorder(Node* v,PositionList& pl)const;
private:
Node* _root;
int n;
};
LinkedBinaryTree::LinkedBinaryTree():_root(NULL),n(0){}
int LinkedBinaryTree::size()const{return n;}
bool LinkedBinaryTree::empty()const{return size()==0;}
LinkedBinaryTree::Position LinkedBinaryTree::root()const{Position(_root);} //canot compile successfully, this error messages is : C:\Users\user\Documents\aa\main.cpp|58|error: return type 'class LinkedBinaryTree::Position' is incomplete
void LinkedBinaryTree::addRoot(){_root=new Node;n=1;}