I have the following classes:
class Node
{
private:
char* m_key;
Node* left;
Node* right;
public:
Node() : m_key(nullptr), left(nullptr), right(nullptr) {}
Node(const char* key)
{
this->m_key = new char[strlen(key) + 1];
strcpy_s(this->m_key, strlen(key) + 1, key);
left = nullptr;
right = nullptr;
}
friend class BinSTree;
};
class BinSTree
{
private:
Node* root;
public:
BinSTree() : root(nullptr) {}
friend std::fstream& operator>>(std::fstream& in, Node* p);
Node* deleteNode(Node* p, const char* key);
~BinSTree();
};
I want to overload the operator>> so when I execute the following code :
Node test("Key");
BinSTree bst;
bst>>test;
the node test is deleted from the bst. The problem is that I can't access the private members from Node and also can't access members of class BinSTree. BinSTree is a class that contains the root of a binary tree.Node is a class that represents a node.
You don't have access to members of BinSTree because first of all your operator>> does not operate on BinSTree at all - it operates on std::fstream& and Node*.
What your code provides is a function for "extracting" Node*s from a std::fstream - it has no relation whatsoever with BinSTree.
The correct signature for the operator you want is
void operator>>(BinSTree& tree, Node* p)
or
BinSTree& void operator>>(BinSTree& tree, Node* p)
(the latter would allow you to chain node extractions).
Related
I'm trying to create a spell checking program in C++ by reading in a dictionary from a .txt file. I've got the read in function working perfectly fine, the issue I'm coming across is when I try to navigate and add to my linked list.
When I try to set the pointer of the newest node to add, to the value of the head pointer, I'm getting an error stating No viable conversion from 'Node' to 'Node *'.
What is the best way to perform this conversion.
I've already tried turning my 'Node Head;' inside of my linked list class to a pointer but receive the same error.
To start I created my Node struct (Declared in a header file)
struct Node
{
private:
std::string word;
Node *nextNode;
public:
//Default constructor
Node();
~Node();
//My Setters and getters for the class
void setWord(std::string _word) { word = _word; }
std::string getWord() { return word; }
void setNode(Node *_nextNode) { nextNode = _nextNode; }
Node getNode() { return *nextNode; }
};
Followed by my LinkedList Class (Also declared in a Header file)
class LinkedList
{
private:
Node head;
int listSize;
public:
LinkedList();
~LinkedList();
void setListSize(int _listSize) { listSize = _listSize; }
int getListSize() { return listSize; }
void setHead(Node _head) { head = _head; }
Node getHead() { return head; }
//Function that adds the next node to the head
void addToHead(LinkedList &myList, Node &myNode);
};
Heres my Function
void LinkedList::addToHead(LinkedList &myList, Node &myNode)
{
myNode.setNode(myList.getHead().getNode());
//Here is where I'm getting my error
//"No viable conversion from 'Node' to 'Node *'
myList.setHead(myNode);
}
The LinkedList class shouldn't own the first Node.
The member head should be a Node* width default value nullptr (the list is empty).
listSize should also have a default value assigned.
LinkedList() head(nullptr), listSize(0) {};
Edit
Personally I would avoid to force the external code to manage the single nodes.
Keep an implementation independent interface.
class LinkedList
{
private:
Node *head_;
int size_;
public:
LinkedList();
~LinkedList();
int size() const { return listSize; }
// insert after the i-th element
void insert(std::size index, std::string const& word);
// return the i-th element
std::string &at(std::size index);
std::string const &at(std::size index) const;
// removes the i-th element
void remove(size::size index);
};
In this way you centralize all list manipulation code into the LinkedList class.
You should also consider problems related to copying a LinkedList object.
How can I create a linked node so that each linked node contains 2 items in a single node? Im not sure if I'm going in the right direction. I have 2 private members in my class, and I'm not sure if I need 2 set functions or if I can have a single set function with 2 parameters. For example void setItem(const string& anItem, const string secondItem);
#ifndef _NODE
#define _NODE
#include<string>
using namespace std;
class Node
{
private:
string item; // A data item
Node* next; // Pointer to next node
public:
Node();
Node(const string& anItem);
Node(const string& anItem, Node* nextNodePtr);
void setItem(const string& anItem);
void setNext(Node* nextNodePtr);
string getItem() const ;
Node* getNext() const ;
}; // end Node
#include "Node.cpp"
#endif
This is my Node.cpp file:
#include "Node.h"
#include <cstddef>
#include<string>
using namespace std;
Node::Node() : next(nullptr)
{
} // end default constructor
Node::Node(const string& anItem) : item(anItem), next(nullptr)
{
} // end constructor
Node::Node(const string& anItem, Node* nextNodePtr) :
item(anItem), next(nextNodePtr)
{
} // end constructor
void Node::setItem(const string& anItem)
{
item = anItem;
} // end setItem
void Node::setNext(Node* nextNodePtr)
{
next = nextNodePtr;
} // end setNext
string Node::getItem() const
{
return item;
} // end getItem
Node* Node::getNext() const
{
return next;
} // end getNext
For me, I'd go for two public functions for setting the two items of the node. One function will modify only one item, while the other function will modify the two item. Like:
// Function that will only set one item
void Node::setIndexItem(const int propNum, const string val)
{
if (propNum == 1) { // You may use 0 for the first item
this.item = val;
} else if (propNum == 2) { // You may use 1 for the second item
this.item2 = val;
} else {
// You may want to raise an exception here. Depends on you really.
}
}
// Function that will set the two items
void Node::setItems(const string val1, const string val2)
{
this.item = val1;
this.item2 = val2;
}
In your case, I would create a dedicated class for the data
struct DataNode
{
std::string key;
std::string value;
};
That separates class responsabilities (List may be focussed to link node).
That would allow you to modify data type without changing your class List (a templated list would be even better, but out of scope).
And then, your Node class would be something like:
class Node
{
private:
DataNode data;
Node* next; // Pointer to next node // I assume you can't use unique_ptr :-/
public:
Node();
Node(const DataNode& data);
Node(const DataNode& data, Node* nextNodePtr);
// Rule of 3
Node(const Node& rhs);
~Node();
Node& operator =(const Node& rhs);
// data accessor
void setItem(const DataNode& data);
const DataNode& getItem() const;
DataNode& getItem();
// Internal utility
void setNext(Node* nextNodePtr);
const Node* getNext() const;
Node* getNext();
};
I added a non-const version of the getter to allow modifying part of the item:
node.getItem().value = "new value";
I've been given the following functions to write
T getMinimum() const {}
and I have to use the following helper function
void getMinimumHelper(Node * subtree, Node * &Location) const {}
However, I've never known how to pass a function like this. I have a binary search tree class with a node as a member of the BST class. I've tried a lot of things such as
Node * minNode = this->Node;
Node minNode = this->getMinimumHelper(findMin, findMin);
return minNode->data;
Helper function:
void getMinimumHelper(Node * subtree, Node * &Location) const {
if (subtree == NULL){
Location = NULL;
}
if (subtree->left == NULL){
Location = subtree;
}
else{
getMinimumHelper(subtreeRoot->left, subtree);
}
}
however I get illegal as right side of '->'
and of course the helper function is void for whatever reason so it doesn't actually return anything. I've been working on this for hours and haven't made any headway at all and cannot figure this out. And I have many more functions with helper functions like this and I have no idea what to do.
Class:
template <class T>
class {
private:
class Node {
public:
T data;
Node * left;
Node * right;
Node * parent;
Node() :left(NULL), right(NULL), parent(NULL) {};
Node(const T& item) {
data = item;
left = NULL;
right = NULL;
parent = NULL;
};
};
public:
BST();
BST(BST&);
~BST();
bool isEmpty() const;
bool search(const T&) const;
private:
Node * _root;
void getMaximumHelper(Node *, Node * &) const;
void getMinimumHelper(Node *, Node * &) const;
};
template <class T>
T BinarySearchTree<T>::getMinimum() const {
Node * minNode;
getMinimumHelper(_root, minNode);
return minNode->data;
};
I have the following implementation for the node class:
template<class T> class binTree; // forward declaration
template<class T> class Node {
friend class binTree<T>; // class binTree is friend
public:
//default constructor
Node(const T& d = T(), Node<T> *l = NULL, Node<T> *r = NULL) : data(d),
left(l), right(r) {};
private:
T data;
Node<T> *left, *right;
};
I'm trying to define a new node a the root of my tree, but I keep getting compilation errors...
template<class T>
void binTree<T>::insert(Node<T>*& n, const T& d){
if(n == NULL)
root = Node<T>(d);
}
I'm confused by the const T& d = T() parameter.
I think you just need to declare the binTree class and its members before you try to define the member. The following code compiles for me:
#include <cstdlib>
template<class T> class binTree; // forward declaration
template<class T> class Node {
friend class binTree<T>; // class binTree is friend
public:
//default constructor
Node(const T& d = T(), Node<T> *l = NULL, Node<T> *r = NULL) : data(d),
left(l), right(r) {};
private:
T data;
Node<T> *left, *right;
};
template <class T> class binTree
{
public:
binTree() { }
void insert(Node<T>*& n, const T& d);
private:
Node<T> root;
};
template<class T>
void binTree<T>::insert(Node<T>*& n, const T& d){
if(n == NULL)
root = Node<T>(d);
}
int main(int argc, char **argv)
{
Node<int>* nt;
binTree<int> btree;
btree.insert(nt, 4);
}
Having said this, your concept of the data structure seems messed up. Why does the insert routine in binTree require a node argument?
I'm not quite sure why you have that default override for the d variable in your default constructor. In my implementation of a Node for my Tree class, I had no default assignment. I think the issue is T(). I would recommend not trying to do that default assignment in the params listing, but instead do it in the BMI List. So it would look kind of like "data(new T), left(NULL), right(NULL)"
Additionally I would say I'm not quite certain as to why you are using T(). If that doesn't work, please post the error code so that we can have a better understanding of what is going on.
I have written a simple LinkedList class. I first have a Node class:
class Node
{
public:
Node* next;
int value;
Node(int val)
{
value = val;
next = NULL;
}
Node(int val, Node* y)
{
value = val;
next = y;
}
}
then implementation for LinkedList is straightforward, with a Node* head member and a addNode(int value) member function.
What are other methods to implement a linked list? could give other such implementations or hint at relevant doc?
Thanks and regards.
The standard library defines a doubly-linked list implementation you can use (see here, for example). I'd advise using that unless you have a very good reason not to.
Boost has some implementations:
http://www.boost.org/doc/libs/1_51_0/doc/html/intrusive/slist.html
http://www.boost.org/doc/libs/1_51_0/doc/html/intrusive/list.html
deleteNode
findNode
Mabe create an iterator.
Also better to use initialisation lists in the constructors and private data members. NULL is for C, use 0 instead.
i.e.
class Node
{
private:
Node* next;
int value;
public:
Node(int val) : next(0), value(val) {}
Node(int val, Node *n) : next(n), value(val) {}
int getVale() { return value}
};