I'm working on a template assignment for class and my code is giving me errors at these specific lines. "'T' is not a valid template type argument for parameter 'T'"
It's real confusing for me because I've never worked with namespaces before. Nor have I worked with an .inl. Could someone help correct my code? I've inserted comments at where the compiler is giving me errors, they're the functions that return a Node*. My code is not finished either.
BST.hpp
#ifndef BST_HPP
#define BST_HPP
namespace Tree{
template<class T>
class BST {
public:
BST();//default constructor
BST(T rootkey);//constructor with 1 parameter for root key
~BST();//destructor
void insert(T value); //function named insert with 1 parameter(key value to insert)
Node* remove(class Node* troot,T value);//function named remove with 1 parameter (key value to remove)
Node* min(class Node* mini);
private:
class Node {
public:
Node();//default constructor
Node(T k);//constructor with 1 parameter (key value)
~Node(); //destructor
Node* getP(); //parent accessor
Node* getL();//left accessor
Node* getR();//right accessor
parent mutator
left mutator
right mutator
operator <
operator ==
operator !=
operator <<
private:
T key;
Node *parent;
Node *left;
Node *right;
};
Node *root;
void destroy(Node* r);
};
};
#include "BST.inl"
#endif
BST.inl
#include "BST.hpp"
template<class T>
inline Tree::BST<T>::BST(T rootkey)
{
root = new Node(rootkey);
root->setP(0);
}
template<class T>
inline Tree::BST<T>::BST()
{
root = new Node();
}
template<class T>
inline Tree::BST<T>::~BST()
{
delete root;
}
template<class T>
inline void Tree::BST<T>::insert(T value)
{
Node *temp = root;
Node *prev;
do
{
if (value < temp->getK())
{
prev = temp;
temp = temp->getL();
}
else if (value >= temp->getK())
{
prev = temp;
temp = temp->getR();
}
} while (temp != NULL);
temp = new Node(value);
temp->setP(prev);
if (temp->getK() > prev->getK())
{
prev->setR(temp);
}
else
{
prev->setL(temp);
}
}
template<class T>
inline Node * Tree::BST<T>::remove(Node *troot, T value)//ERROR
{
Node *temp;
if (troot == NULL)
{
return troot;
}
else if (value > troot->getK())
{
return remove(troot->getR(), value)
}
else if (value < troot->getK())
{
return remove(troot->getL(), value)
}
else
{
if (troot->getL() == NULL && troot->getR() == NULL)
{
delete troot;
troot = NULL;
return troot;
}
else if (troot->getR() == NULL)
{
temp = troot;
troot = troot->getL();
return troot;
}
else if (troot->getL() == NULL)
{
temp = troot;
troot = troot->getR();
return troot;
}
else
{
temp = min(troot->getR());
troot->setK(temp->getK());
troot->getR() = remove(troot->getR, temp->getK());
}
}
return troot;
}
template<class T>
inline Node * Tree::BST<T>::min(Node * mini)//ERROR
{
if (mini->getL() != NULL)
{
mini = mini->getL();
}
else
return mini;
}
template<class T>
inline Tree::BST<T>::Node::Node()
{
key = 0;
}
template<class T>
inline Tree::BST<T>::Node::Node(T k)
{
key = k;
}
template<class T>
inline Tree::BST<T>::Node::~Node()
{
delete getL();
delete getR();
}
template<class T>
inline Node * Tree::BST<T>::Node::getP()//ERROR
{
return parent;
}
template<class T>
inline Node * Tree::BST<T>::Node::getL()//ERROR
{
return left;
}
In this line:
template<class T>
inline Node * Tree::BST<T>::Node::getP() {
There is no Node class at global scope for you to return. That's the only thing Node can refer to so far, since the compiler is still not inside BST<T>'s scope to find the internal Node. There are two ways to fix this:
Fully qualify the Node (works since C++98):
template<class T>
inline Tree::BST<T>::Node * Tree::BST<T>::Node::getP() {
This fully qualifies the scope where Node is.
Use a trailing return type (my personal preference, C++11 and onward):
template<class T>
inline auto Tree::BST<T>::Node::getP() -> Node* {
This delays the lookup of Node until it may begin inside the scope of the class.
Related
I'm trying to create a binary search tree by keeping the path: each node has a link to its parent. Below is the classic binary search. How do I change it to be able to solve my problem?
I tried adding the "father" pointer to the struct but I have no problems understanding how and when to save it. I am new to this language so be patient. thank you so much
#include <iostream>
template <class T>
class BinaryTree
{
struct node {
T value;
struct node* right;
struct node* left;
};
public:
BinaryTree();
~BinaryTree();
void add(T val);
void printPreOrder();
void printInOrder();
void printPostOrder();
int size();
bool lookup(T val);
private:
struct node* root;
int treeSize;
void add(struct node** node, T val);
bool lookup(struct node* node, T val);
void printPreOrder(struct node* node);
void printInOrder(struct node* node);
void printPostOrder(struct node* node);
void deleteTree(struct node* node);
};
template <class T>
BinaryTree<T>::BinaryTree() {
this->root = NULL;
this->treeSize = 0;
}
template <class T>
BinaryTree<T>::~BinaryTree() {
deleteTree(this->root);
}
template <class T>
int BinaryTree<T>::size() {
return this->treeSize;
}
template <class T>
void BinaryTree<T>::add(T val) {
add(&(this->root), val);
}
template <class T>
void BinaryTree<T>::add(struct node** node, T val) {
if (*node == NULL) {
struct node* tmp = new struct node;
tmp->value = val;
tmp->left = NULL;
tmp->right = NULL;
*node = tmp;
this->treeSize++;
}
else {
if (val > (*node)->value) {
add(&(*node)->right, val);
}
else {
add(&(*node)->left, val);
}
}
}
template <class T>
void BinaryTree<T>::printInOrder() {
printInOrder(this->root);
std::cout << std::endl;
}
template <class T>
void BinaryTree<T>::printInOrder(struct node* node) {
if (node != NULL) {
printInOrder(node->left);
std::cout << node->value << ", ";
printInOrder(node->right);
}
}
template <class T>
void BinaryTree<T>::printPreOrder() {
printPreOrder(this->root);
std::cout << std::endl;
}
template <class T>
void BinaryTree<T>::printPreOrder(struct node* node) {
if (node != NULL) {
std::cout << node->value << ", ";
printInOrder(node->left);
printInOrder(node->right);
}
}
template <class T>
void BinaryTree<T>::printPostOrder() {
printPostOrder(this->root);
std::cout << std::endl;
}
template <class T>
void BinaryTree<T>::printPostOrder(struct node* node) {
if (node != NULL) {
printInOrder(node->left);
printInOrder(node->right);
std::cout << node->value << ", ";
}
}
template <class T>
void BinaryTree<T>::deleteTree(struct node* node) {
if (node != NULL) {
deleteTree(node->left);
deleteTree(node->right);
delete node;
}
}
template <class T>
bool BinaryTree<T>::lookup(T val) {
return lookup(this->root, val);
}
template <class T>
bool BinaryTree<T>::lookup(struct node* node, T val) {
if (node == NULL) {
return false;
}
else {
if (val == node->value) {
return true;
}
if (val > node->value) {
return lookup(node->right, val);
}
else {
return lookup(node->left, val);
}
}
}
I will give you the recursive solution since it is the natural way to implement it:
First it would be a good idea to define a constructor in your struct like so:
node(T value, node* left = nullptr, node* right = nullptr){
this->value = value;
this->left = left;
this->right = right;
}
Take out the struct in the struct node* root.
void insert(T value){
Node* temp = root;
insert(value, root);
}
//helper function
void insert(T value, Node* root){
if(root->left == nullptr && root->right == nullptr){
if(root->value < value){
root->left = new Node(value);
}
else{
root->right = new Node(value);
}
return;
}
if(value < root->value)insert(value, root->left);
else{
insert(value, root->right);
}
}
Not sure where you got your code it does not look correct....
I don't understand the need for pointer to pointer to struct node in your code. Pointer to struct node would suffice. As far as your question goes, you can pass the parent of current node as a third parameter in the method add. Initially it will be null. Now incase you have to go down to the child of the current node, then the current node becomes it's parent. When you have to allocate memory for value val, set the it's parent there.
template <class T>
void BinaryTree<T>::add(struct node** node, T val, struct node* parent = nullptr) {
if (*node == NULL) {
struct node* tmp = new struct node;
tmp->value = val;
tmp->left = NULL;
tmp->right = NULL;
temp->parent = parent;
*node = tmp;
this->treeSize++;
}
else {
if (val > (*node)->value) {
add(&(*node)->right, val, *node);
}
else {
add(&(*node)->left, val, *node;
}
}
}
so I have an assignment where I need to create a doubly linked list and then create a stack and queue class and inherit from the linkedlist class in order to create an RPN calculator. So far I have created my doubly linkedlist class and the other to classes. However, I am having trouble understanding how I will inherit and use the linked list class with the stack and queue. I will provide what I have so far.
I have gone to tutoring and have not had much help so I thought I would look for some extra help, do not want homework done for me but to just be pointed in the right direction.
Stack.h
using std::iterator;
using std::vector;
using std::string;
template<class T>
class Stack : public vector<T>
{
private:
T getElement(bool erase);
typename std::vector<T> ::iterator pEnd;
T top;
public:
Stack();
T pop();
T peek();
void push(T elem);
};
template<class T>
Stack<T>::Stack()
{
}
template<class T>
void Stack<T>::push(T elem)
{
this->push_back(elem);
}
template<class T>
T Stack<T>::peek()
{
return this->getElement(false);
}
template<class T>
T Stack<T>::pop()
{
return this->getElement(true);
}
template<class T>
T Stack<T>::getElement(bool erase)
{
this->pEnd = this->end() - 1;
T tmp;
if (this->size() > 0)
{
tmp = *this->pEnd;
if (erase) {
this->erase(pEnd);
}
}
return tmp;
}
Queue.h
using namespace std;
class Queue
{
private:
int items[MAXQUEUE];
int head;
int tail;
public:
Queue();
bool isEmpty();
bool isFull();
bool enqueue(int item);
int dequeue();
int peek();
};
Queue::Queue()
:head(QEMPTY), tail(QEMPTY)
{
}
bool Queue::isEmpty()
{
return this->head == this->tail;
}
bool Queue::isFull()
{
return this->tail == MAXQUEUE;
}
bool Queue::enqueue(int item)
{
if (this->isFull())
return false;
this->items[this->tail] = item;
tail = (tail + 1) % MAXQUEUE;
return true;
}
int Queue::dequeue()
{
if (this->isEmpty())
return EMPTY;
int item = this->items[head];
this->head = (this->head + 1) % MAXQUEUE;
return item;
}
int Queue::peek() {
return this->tail;
}
doublylinkedlist.h
using std::iterator;
using std::vector;
using std::string;
/*START OF NODE CLASS*/
/*---------------------------------------------*/
template<class T>
struct Node
{
T Data;
T Search;
T value;
Node<T>*Next;
Node<T>*Prev;
};
template<class T>
class LinkedList
{
private:
Node<T> *Head;
public:
LinkedList();
void addNode(T Data);
void deleteNode(T Search);
void insert(T Search, T value);
void printListBackwards();
void printListForwards();
};
template<class T>
LinkedList<T>::LinkedList()
{
this->Head = NULL;
}
template<class T>
void LinkedList<T>::addNode(T data)
{
if (Head == NULL)
{
Head = new Node<T>;
Head->Data = data;
Head->Next = NULL;
Head->Prev = NULL;
}
else
{
Node<T>*p = this->Head;
while (p->Next != NULL)
p = p->Next;
Node<T>*n = new Node<T>;
n->Data = data;
n->Next = NULL;
p->Next = n;
n->Prev = p;
}
}
template<class T>
void LinkedList<T>::insert(T Search, T value)
{
Node *p = Head;
while (p->Data != Search)
{
p = p->Next;
}
Node *n = new Node;
n->Data = value;
n->Next = p->Next;
p->Next = n;
}
template<class T>
void LinkedList<T>::deleteNode(T Search)
{
Node *p = Head;
while (p->Next->Data != Search)
{
p = p->Next;
}
Node *delPtr = p->Next;
p->Next = p->Next->Next;
delete delPtr;
}
template<class T>
void LinkedList<T>::printListBackwards()
{
Node<T> *p = Head;
while (p->Next != NULL)
{
p = p->Next;
}
while (p != NULL)
{
cout << p->Data<< endl;
p = p->Prev;
}
}
template<class T>
void LinkedList<T>::printListForwards()
{
Node<T> *p = Head;
while (p != NULL)
{
cout << p->Data << endl;
p = p->Next;
}
}
A doubly linked list can be added to at the head or the tail, and removed at the tail.
A stack pushes at one end (the head?) and pops at the same end (the head).
A queue pushes at one end (the tail) and pops at the other end (the head).
For some reason, I keep getting a "template agrument 1 is invalid error" when compiling my code. I'm not sure why. I'm trying to create a linked list using templates. Here is my code
When running my main method where I introduce the class as:
Dlist<L> list;
Then I try to implement a few of the functions.
The error I get is:
Dlist<L> list; template agrument 1 is invalid.
^
HELP
ListNode.H
#ifndef LISTNODE_H
#define LISTNODE_H
#include <iostream>
using namespace std;
template <class L>
class ListNode
{
public:
L data;
ListNode *prev;
ListNode *next;
ListNode(L d);
ListNode();
~ListNode();
};
template <class L>
ListNode<L>::ListNode()//blank constructor
{
}
template <class L>
ListNode<L>::ListNode(L d)//overloaded constructor
{
next = NULL;
prev = NULL;
data = d;
}
template <class L>
ListNode<L>::~ListNode()//deconstructor
{
next = NULL;
prev = NULL;
}
#endif
DList.h
#ifndef DLIST_H
#define DLIST_H
#include <iostream>
#include "ListNode.h"
using namespace std;
template <class L>
class Dlist
{
private:
ListNode<L>* front;
ListNode<L>* back;
unsigned int size;
public:
Dlist();//constructor
~Dlist();//destructor
//insert and remove functions
void insertFront(L data);
int removeFront();
void insertBack(L data);
int removeBack();
ListNode<L>* removeAt(L pos);
//other functions
bool isEmpty();
int find(L val);
int getFront();
int getBack();
unsigned int getSize();
void printList();
};
template <class L>
Dlist<L>::Dlist()
{
size = 0;
front = NULL;
back = NULL;
}
template <class L>
Dlist<L>::~Dlist()
{
if(front != NULL)
{
delete front;
}
}
template <class L>
void Dlist<L>::insertFront(L data)
{
ListNode<L> *node = new ListNode<L>(data);
if (size = 0)
{
back = node;
}
else
{
front->prev=node;
node->next=front;
}
size++;
front = node;
}
template <class L>
int Dlist<L>::removeFront()
{
ListNode<L> *temp = front;
if(front->next = NULL)
{
back = NULL;
}
else
{
front->next->prev = NULL;
front->next = NULL;
}
front = front->next;
int val = temp->data;
delete temp;
--size;
return val;
}
template <class L>
void Dlist<L>::insertBack(L data)
{
ListNode<L> *node = new ListNode<L>(data);
if (size == 0)
{
front = node;
}
else
{
back->next = node;
node->prev = back;
}
back = node;
size++;
}
template <class L>
int Dlist<L>::removeBack()
{
ListNode<L> *temp = back;
if(back->prev = NULL)
{
front = NULL;
}
else
{
back->prev->next = NULL;
}
back = back->prev;
int val = temp->data;
delete temp;
--size;
return val;
}
template <class L>
ListNode<L>* Dlist<L>::removeAt(L key)
{
ListNode<L>* curr = front;
while(curr->data != key)
{
curr=curr->next;
if (curr == NULL)
{
return NULL;
}
}
//found the key
if(curr == front)
{
front=curr->next;
}
else
{
curr->prev->next = curr->next;
}
if(curr==back)
{
back = curr->prev;
}
else
{
curr->next->prev = curr->prev;
}
curr->next=NULL;
curr->prev = NULL;
size--;
return curr;
}
template <class L>
unsigned int Dlist<L>::getSize()
{
return size;
}
template <class L>
void Dlist<L>::printList()
{
ListNode<L>* curr = front;
while(curr != NULL)
{
cout<< curr->data << endl;
curr = curr->next;
}
}
template <class L>
int Dlist<L>::getFront()
{
return front;
}
template <class L>
int Dlist<L>::getBack()
{
return back;
}
#endif
you can not use the template class as you are trying.
Dlist< L> list;
As L is not a valid data type. Valid data type includes built-in or user defined data type.
"L" you are using it as a template so you can use it only inside the template class.
The above statement would be valid if you define your own class 'L' like below:
class L
{
int a;
};
Hope that helps.
I am trying to implement BST with unique_ptr. I want to return the node with the minimum value in BST. I know how to return the minimum value and I wrote the function for it but what if I want to return node? Is it possible with the classes I have?
#include <iostream>
#include <memory>
template<class T>
class BinarySearchTree{
struct TreeNode;
typedef std::unique_ptr<TreeNode> spTreeNode;
struct TreeNode{
T data;
spTreeNode left;
spTreeNode right;
TreeNode(const T & value):data(value),left(nullptr),right(nullptr){}
};
spTreeNode root;
bool insert(spTreeNode &node);
void print(const spTreeNode&) const ;
public:
BinarySearchTree();
void insert( const T & node);
void print()const;
T getMin();
};
template<class T>
BinarySearchTree<T>::BinarySearchTree():root(nullptr){}
template<class T>
void BinarySearchTree<T>::insert(const T & ref)
{
std::unique_ptr<TreeNode> node(new TreeNode(ref));
if (root == nullptr) {
root = std::move(node);
} else {
TreeNode* temp = root.get();
TreeNode* prev = root.get();
while (temp != nullptr) {
prev = temp;
if (temp->data < ref)
temp = temp->right.get();
else
temp = temp->left.get();
}
if (prev->data < ref)
prev->right = std::move(node);
else
prev->left = std::move(node);
}
}
template<class T>
T BinarySearchTree<T>::getMin()
{
TreeNode* temp = root.get();
TreeNode *prev = nullptr;
while (temp)
{
prev = temp;
temp = temp->left.get();
}
return prev->data;
}
int main()
{
BinarySearchTree<int> bst;
bst.insert(13);
bst.insert(3);
bst.insert(5);
bst.insert(31);
bst.insert(511);
bst.insert(311);
std::cout << bst.getMin(); // Works but what if I want to return the Node?
return 0;
}
You would have to decide the interface you want. Do you want to return a const pointer to the extant TreeNode? A const reference to the TreeNode? A copy of the TreeNode? The key is to think about how long references/pointers will be valid.
I frankly don't think any of those are good ideas for a public interface. So let's say you made getMinNode() private, and kept getMin() public:
// Returns non-owning pointer; do not attempt to delete TreeNode.
template<class T>
const BinarySearchTree<T>::TreeNode* BinarySearchTree<T>::getMinNode() const
{
// Like getMin(), but return prev
// Does this work for empty BinarySearchTree?
TreeNode* temp = root.get();
TreeNode *prev = nullptr;
while (temp)
{
prev = temp;
temp = temp->left.get();
}
return prev;
}
template<class T>
T BinarySearchTree<T>::getMin() const // member function is const
{
return getMinNode()->data;
}
I'm trying to implement those two functions "extract" and "deleteList" and I somehow can't get my head around it.
I know how a linked-list works but I'm new to programming and just can't figure out an algorithm. Could I ask for some tips?
I want the extract function to return a list of values that fulfill the predicate and remove those from the original list (thats why its passed as a reference).
I want the delete function to delete all those that are the same as those passed from the argument
My code looks like this:
#include <iostream>
#include <string>
using namespace std;
template <typename T>
struct Node
{
T data;
Node* next;
};
template <typename T>
void showList(const Node<T>* head)
{
while(head->next != NULL)
{
cout<<head->data<<" ";
head = head->next;
}
cout<<endl;
}
template <typename T>
Node<T>* arrayToList(const T tab[], size_t size)
{
Node<T> *prev;
for(int i = size-1; i>=0 ; i--){
Node<T> *p = new Node<T>;
p->data = tab[i];
p->next = prev;
prev = p;
}
return prev;
}
template<typename T>
Node<T>* extract(Node<T>*& head, bool (*predicate)(const T&))
{
}
template <typename T>
void deleteList(Node<T>*& head)
{
//delete passed in
}
bool isEven(const int& n)
{
return n%2 == 0;
}
bool isLong(const string& s)
{
return s.size() >=5;
}
Thank you guys!
Firstly, your showList() has a potential problem with dereferencing
a null pointer. So it should look like this:
template <typename T>
void showList(const Node<T>* head)
{
while(head != NULL)
{
cout << head->data << " ";
head = head->next;
}
cout << endl;
}
Secondly, it is more convenient to have auxiliary functions like
pushToList() and popFromList():
template <typename T>
void pushToList(Node<T>*& head, const T &element)
{
Node<T> *p = new Node<T>;
p->data = element;
p->next = head;
head = p;
}
template <typename T>
T popFromList(Node<T>*& head)
{
T value;
if (head != NULL) {
Node<T>* tmp = head;
value = head->data;
head = head->next;
delete tmp;
}
return value;
}
You can rewrite your arrayToList() using pushToList():
template <typename T>
Node<T>* arrayToList(const T tab[], size_t size)
{
Node<T>* head = NULL;
for(int i = size - 1; i >= 0; i--){
pushToList(head, tab[i]);
}
return head;
}
And implement deleteList() using popFromList():
template <typename T>
void deleteList(Node<T>*& head)
{
while (head != NULL) {
popFromList(head);
}
}
exctract() also can be implemented in terms of push and pop. You
just create two temporary lists and push to them according to the
predicate:
template<typename T>
Node<T>* extract(Node<T>*& head, bool (*predicate)(const T&))
{
Node<T> *extracted = NULL;
Node<T> *rest = NULL;
while (head != NULL) {
T value = popFromList(head);
if (predicate(value)) {
pushToList(extracted, value);
} else {
pushToList(rest, value);
}
}
reverseList(extracted);
reverseList(rest);
head = rest;
return extracted;
}
One problem is after the main work the temporary lists are
reversed. So we need the reverseList() function, which can be also
implemented in terms of push and pop:
template <typename T>
void reverseList(Node<T>*& head)
{
Node<T> *result = NULL;
while(head != NULL) {
pushToList(result, popFromList(head));
}
head = result;
}
It is not a very effective implementation but I think it does the work.
I've put the complete source code here.