I have created a node.h class, defining a class called node for representing a binary tree(any type). It seems to be that the constructor isn't working. The errors are below.Ive only started writing constructors within classes like these, and this is the first ive encountered binary trees. Can anyone point me in the right direction on how to fix these errors and make my code work? Thanks.
Node.h
#ifndef NODE_H
#define NODE_H
#include <iostream>
//an object of type node holds 3 things
// - an item (oftype t)
// - a left subtree
// - a right subtree
template<typename T>
class Node {
public:
Node(T item); //constructor to create a leaf node
Node(T item, Node *lft, Node *rht); //constructor which creates an internal node
~Node(); //Destructor
//public data member functions:
bool searchTree(T key);
void printTree();
private:
//private data member functions:
//..
};
//constructor
template<typename T>
Node<T>::Node(T i, Node<T> *l, Node<T> *r) {
item = i;
lft = NULL;
rht = NULL;
}
//constructor //is this correct?
template <typename T>
Node<T>::Node(T i) { //should i be a parameter here?
item = i; //is this right?
}
//destructor
template <typename T>
Node<T>::~Node() {
delete left;
delete right;
//delete;
}
//print tree method
template <typename T>
void Node<T>::printTree() {
if (lft != NULL) {
lft->printTree();
cout << item << endl;//alphabetical order
}
if (rht != NULL) {
rht->printTree();
//cout << item << endl; //post order
}
}
//search Tree method
template <typename T>
bool Node<T>::searchTree(T key) {
bool found = false;
if (item == key) {
return true;
}
if (left != NULL) {
found = left->searchTree(key);
if (found) return true;
}
if (right != NULL) {
return right->searchTree(key);
}
return false; //if left and right are both null & key is not the search item, then not found == not in the tree.
}
#endif
Main.cpp
#include "Node.h"
#include <iostream>
using namespace std;
//set up tree method
Node<string> *setUpTree() {
Node<string> *s_tree =
new Node<string>("Sunday",
new Node<string>("monday",
new Node<string>("Friday"),
new Node<string>("Saturday")),
new Node<string>("Tuesday",
new Node<string>("Thursday"),
new Node<string>("Wednesday")));
}
int main() {
Node<string> *s_tree;
s_tree = setUpTree();
cout << "Part 2 :Priting tree vals " << endl << endl;
s_tree->printTree();
cout << endl;
//search for range of tree values
//searchTree(s_tree, "Sunday");
//searchTree(s_tree, "Monday");
return 0;
}
There is no declarations of members you use in your constructor and other methods. The compiler does not know what rht or right means. Judging from your code the class should look more like this:
template<typename T>
class Node {
public:
Node(T item); //constructor to create a leaf node
Node(T item, Node *lft, Node *rht); //constructor which creates an internal node
~Node(); //Destructor
//public data member functions:
bool searchTree(T key);
void printTree();
private:
Node* left;
Node* right;
T item;
//private data member functions:
//..
};
So now the compiler knows what left, right and item mean. Now you can use these identifiers inside member functions of that class. Note that compiler still does not know what rht or lft are, so you should replace them with right and left.
Hope this helps
Related
I'm new to working with class templates and am simply trying to define a temporary node 'temp' in a class associated with the Linked List, which sets the string that the node stores to some temporary string that is created in the function TowerHanoi::set_Discs(size_t disc) via user input. When I call the function temp->set_data(tmp_str) i get a segmentation fault. I tried calling temp->set_data("hello"); on its own and i still get the error.
I'm not sure what's going on here and i've tried researching into it but to no avail. I'm probably missing something obvious, but i'm just quite lost now. Let me know if you need more code. Thanks.
TowerHanoi.cpp:
#include "TowerHanoi.h"
#include <iostream>
#include <cstdlib>
using namespace std;
using oreilly_A2::node;
namespace oreilly_A2 {
TowerHanoi::TowerHanoi() {
for (int i=0;i<2;i++) {
rod[i] = LStack<node<std::string> >();
}
}
TowerHanoi::TowerHanoi(size_t numDiscs) {
for (int i=0; i < 2; i++) {
rod[i] = LStack<node<string> >();
}
discs = numDiscs;
}
void TowerHanoi::set_Discs(size_t disc) {
node<string>* temp=NULL;
while (disc != 0) {
string tmp_str;
for (size_t i=0; i<disc; i++) {
tmp_str.append("x");
}
disc--;
temp->set_data(tmp_str);
rod[0].push(temp);
}
void TowerHanoi::print_Game() {
for (size_t s=1; s<discs; s++) {
cout << " ";
for (size_t o=1; o<discs-s;o++) {
cout << " ";
}
//cout << tmp_node->data() << endl;
cout << "x" << endl;
}
}
}
node.h file:
#ifndef NODE_CAMERON_H
#define NODE_CAMERON_H
#include <string>
namespace oreilly_A2 {
template <typename Item>
class node {
public:
node(); //constructor for node
node(const Item val, node* newNext); //constructor with parameters
~node(); //destructor
void set_data(Item new_data); //set the word that this node contains
void set_link(node* new_link); //set the 'next' node
void set_previous(node* new_prev);
Item data() const; //return this node's word
const node* link() const; //return next
const node* back() const;
node* link(); //return next
node* back();
private:
node* next; //the next node
node* previous;
Item word; //the word this node contains
};
}
#include "Node.template"
#endif
node.template file:
namespace oreilly_A2 {
template <typename Item>
node<Item>::node() {
next=NULL;
previous=NULL;
}
//Node.template
template <typename Item>
node<Item>::node(const Item val, node* newNext=NULL) {
word = val;
next = newNext;
}
template <typename Item>
node<Item>::~node() {
delete next;
delete previous;
delete word;
}
template <typename Item>
void node<Item>::set_data(Item new_data){
word = new_data;
}
template <typename Item>
void node<Item>::set_link(node* new_link){
next = new_link;
}
template <typename Item>
void node<Item>::set_previous(node* new_back) {
previous = new_back;
}
template <typename Item>
Item node<Item>::data() const { //return the word
return word;
}
template <typename Item>
const node<Item>* node<Item>::link() const { //return next node (const function)
return next;
}
template <typename Item>
const node<Item>* node<Item>::back() const { //return previous node (const)
return previous;
}
template <typename Item>
node<Item>* node<Item>::link() {
return next; //return next node (non-const)
}
template <typename Item>
node<Item>* node<Item>::back() { //return previous node (const)
return previous;
}
}
Unless I have missed something the temp variable is NULL at the time of calling set_data. As any regular object you need to first initialized it.
node<string>* temp=new node<string>();
And then freeing it when appropriate to avoid memory leaks.
This is not the case with temp_str because the later is not a pointer, it's a value so it gets initialized automatically (and also freed automatically when it gets out of scope).
You have initialized temp as NULL. So when you are trying to do temp->set_data(tmp_str); you are actually trying to access NULL pointers.
All you need to do is initialize temp. I have correct the code below
void TowerHanoi::set_Discs(size_t disc) {
node<string>* temp=new node<string>();
while (disc != 0) {
string tmp_str;
for (size_t i=0; i<disc; i++) {
tmp_str.append("x");
}
disc--;
temp->set_data(tmp_str);
rod[0].push(temp);
}
To avoid memory leak you need to delete all the memory allocated after you are done.
I need help with these codes that will ask for 3 input integers(AddToFront function) and then display them in last-to-first order, ex; input 1=1 input 2=2 input 3=3 and then these will be displayed as 3 2 1...
I've been trying to reverse it to first-to-last order with the AddToLast function..I understand how the linked list works,i think,but i am having problems turning it to codes..Also if someone could please explain to me how to set the pTail as the last node, that would be helpfull..
Thanks in advance to anyone that could help..
//List.h
//Declaration of class List
#ifndef LIST_H
#define LIST_H
template <class DataType>
class List
{
private:
class Node
{
public:
DataType data;
Node *link;
};
Node *pHead;
Node *pCurr;
Node *pTail;
int numItem;
public:
List();
~List();
void AddToFront();
void AddToLast();
bool Traverse(DataType, int&);
void printData();
int NoOfItem();
};
#endif
//Define the implementation of all methods in class List
template <class DataType>
List<DataType>::List(){
numItem=0;
pHead=0;
pTail; //knp x boleh????
}
template <class DataType>
List<DataType>::~List(){}
//template <class DataType>
//void List<DataType>::AddToFront()
//{
// DataType item;
// Node *pNew = new Node;
// cout<<"Enter data: ";
// cin>>item;
// pNew->data=item; //put item in node pnew
// pNew->link=pHead; //use pHead link for pNew
// pHead=pNew; //make pNew as pHead
// numItem++;
//}
template <class DataType>
void List<DataType>::AddToLast()
{
DataType item;
Node *pNew = new Node;
cout<<"Enter data: ";
cin>>item;
pNew->data=item;
pNew->link=pHead;
pHead=pNew;
pNew->NUll;
numItem++;
}
template <class DataType>
void List<DataType>::printData()
{
pCurr=pTail;
while (pCurr!=0)
{
cout<<pCurr->data<<" ";
pCurr=pCurr->link;
}
cout<<"\n";
}
template <class DataType>
int List<DataType>::NoOfItem()
{ return numItem; }
template <class DataType>
bool List<DataType>::Traverse(DataType target,int& loc)
{
if (numItem==0)
cout<<"There is no item in the list."<<endl;
else
{
pCurr=pHead;
loc=0;
while (pCurr->data !=target && pCurr->link !=0)
{
pCurr=pCurr->link;
loc++;
}
if (pCurr->data==target)
return true;
else
return false;
}
}
//ListMain.cpp
#include <iostream>
#include "List.h"
using namespace std;
void main()
{
int target, loc;
List<int> x;
for (int i=1;i<4;i++)
{
x.AddToLast();
}
cout<<"\nMumber of item Now : "<<x.NoOfItem();
cout<<"\nThe List are : "<<endl;
x.printData();
cout<<"\nEnter the search item : ";
cin>>target;
if (x.Traverse(target,loc)==true)
{
cout<<"Item is found at location : "
<<loc<<endl;
}
else
{
cout<<"Item is not found. \n";
}
}
Traverse() looks ok to me, although its algorithm is somewhat convoluted. Also, there's no need to use a class member, just for the benefit of that method. This is what locally-scoped variables are for.
All that code, the entire function, can simply be replaced by
template <class DataType>
bool List<DataType>::Traverse(DataType target,int& loc)
{
Node *p;
for (p=pHead; p; p=p->link)
if (p->data == target)
return true;
return false;
}
That certainly looks much simpler, compared to all of what you have, so far.
As far as setting pTail, I think you can figure it out yourself after considering the following facts:
Initially, in the constructor, the list is empty, so pTail would naturally be null.
You're always adding to the head, therefore, the very first node added to the list will be its permanent tail node.
After you set pTail it will no longer be null.
Therefore, when adding a new node to the head, if pTail is null, this must be the new permanent tail node.
I have a binary search tree class (BST.h) and a node class (Node.h) of which works fine when I store data types such as integers in it. My problem is trying store class objects in my BST and use an attribute from the object as the key. My program also has a student class which contains studentID and studentName. How would I write an operator overload in my student class so every time my BST preforms operation on nodes, it will overload to the student.getID(), instead of operating on the object itself. I have the rough idea of what the overload function should look like but i don't know where it should go or if its coded correctly anyway.
//My attempt at an operator overload
bool operator< (const Student &s1, const Student &s2)
{
return s1.GetID < s2.GetID;
}
//Node.h
#ifndef NODE_H
#define NODE_H
#include <iostream>
using namespace std;
template<class T>
class Node
{
public:
Node();
T data;
Node *left;
Node *right;
Node(T);
};
template<class T>
Node<T>::Node()
{
}
template<class T>
Node<T>::Node(T d)
{
data = d;
left = NULL;
right = NULL;
}
#endif //
//BST.h
#ifndef BST_H
#define BST_H
#include <iostream>
#include "Node.h"
#include <string>
using namespace std;
template<class T>
class BST
{
public:
BST();
void Insert(T);
Node<T> *Search(T);
void preOrder();
void inOrder();
void postOrder();
~BST();
private:
Node<T> *root;
void Insert(T , Node<T> *aNode);
Node<T> *Search(T, Node<T> *aNode);
void preOrder(Node<T> *aNode);
void inOrder(Node<T> *aNode);
void postOrder(Node<T> *aNode);
};
template<class T>
BST<T>::BST()
{
root = NULL;
}
template<class T>
void BST<T>::Insert(T data, Node<T> *aNode)
{
if (data < aNode->data)
{
if (aNode->left != NULL)
{
Insert(data, aNode->left);
}
else
{
aNode->left = new Node<T>(data);
aNode->left->left = NULL;
aNode->left->right = NULL;
}
}
else
{
if (data >= aNode->data)
{
if (aNode->right != NULL)
{
Insert(data, aNode->right);
}
else
{
aNode->right = new Node<T>(data);
aNode->right->left = NULL;
aNode->right->right = NULL;
}
}
}
}
template<class T>
void BST<T>::Insert(T data)
{
if (root != NULL)
{
Insert(data, root);
}
else
{
root = new Node<T>(data);
root->left = NULL;
root->right = NULL;
}
}
template<class T>
Node<T>* BST<T>::Search(T data, Node<T> *aNode)
{
if (aNode != NULL)
{
if (data == aNode->data)
{
return aNode;
}
if (data < aNode->data)
{
return Search(data, aNode->left);
}
else
{
return Search(data, aNode->right);
}
}
else
{
return NULL;
}
}
template<class T>
Node<T>* BST<T>::Search(T data)
{
return Search(data, root);
}
template<class T>
void BST<T>::preOrder()
{
preOrder(root);
}
template<class T>
void BST<T>::preOrder(Node<T> *aNode)
{
if (aNode != NULL)
{
cout << aNode->data << " ";
preOrder(aNode->left);
preOrder(aNode->right);
}
}
template<class T>
void BST<T>::inOrder()
{
inOrder(root);
}
template<class T>
void BST<T>::inOrder(Node<T> *aNode)
{
if (aNode != NULL)
{
inOrder(aNode->left);
cout << aNode->data << " ";
inOrder(aNode->right);
}
}
template<class T>
void BST<T>::postOrder()
{
postOrder(root);
}
template<class T>
void BST<T>::postOrder(Node<T> *aNode)
{
if (aNode != NULL)
{
postOrder(aNode->left);
postOrder(aNode->right);
cout << aNode->data << " ";
}
}
template<class T>
BST<T>::~BST()
{
}
#endif // !BST_H
//Student.h
#ifndef STUDENT_H
#define STUDENT_H
#include <iostream>
#include <string>
using namespace std;
class Student
{
public:
Student();
Student(string, int);
~Student();
int Student::GetID();
private:
string name;
int ID;
};
inline int Student::GetID()
{
return ID;
}
You seem to be asking about operator< taking Students , however Student is not a class template, so the title of your post is baffling.
As someone else pointed out, your operator< is almost correct, except you have to actually call GetID() instead of comparing pointers to member functions.
This won't work yet until you fix GetID however. Instead of int Student::GetID(); it should be:
int GetID() const;
The const means that it can be called on objects passed by const reference, as you have in your operator< implementation. And you don't repeat the Student:: when declaring functions inside the class. (You use it when defining class members outside of the class definition).
Declare it as a friend function within your Student class, next to the rest of your member functions
friend bool operator < (Student& s1, Student& s2);
Your implementation is correct, it should go outside your Student class within the same header file.
I'm trying to implement BST in c++ using recursion. However, I found myself in dilemma.
In the Insert function, I use reference TreeNode *&nodeto pass the function argument. I don't want make the reference const, because I need change node in Insert function. On the other side, when I call function like tree.Insert(10, tree.Getroot()), it occurs error because function Getroot creates temporary variable which can't not be assigned to non-const reference. And I know I can easily fix it by making the TreeNode *rootpublic, but I don't want do that.
What should I do to fix it or is there any better design? Please help, thanks in advance.
Here's the head file.
#ifndef BINARY_SEARCH_TREE_H
#define BINARY_SEARCH_TREE_H
class TreeNode
{
public:
TreeNode(int x = 0,TreeNode* l = nullptr, TreeNode* r = nullptr)
: element(x), left(l), right(r) { }
int element;
TreeNode* left;
TreeNode* right;
};
class BST
{
public:
BST(TreeNode *t = nullptr) : root(t) {}
void Insert(int x, TreeNode*& node)
{
if (node == nullptr) {
node = new TreeNode(x, nullptr, nullptr);
if (node == nullptr)
std::cout << "Insert Failure" << std::endl;
}
else if (node->element < x) {
Insert(x, node->right); //easy to make a mistake
}
else if (node->element > x) {
Insert(x, node->left);
}
}
TreeNode *Getroot()
{
return root;
}
private:
TreeNode* root;
};
#endif
Implement Insert at a node level as well as tree level. Then the insert logic should either be handled at the root level by the tree or at depth by the node you're inserting at. I have an example tree implemented here. It might not be the best implementation but maybe it will be useful to you.
#ifndef __BINARYTREENODE__
#define __BINARYTREENODE__
class BinaryTreeNode {
public:
BinaryTreeNode(int);
int element;
BinaryTreeNode *left;
BinaryTreeNode *right;
};
#endif /* __BINARYTREENODE__ */
#ifndef __BINARYSEARCHTREE__
#define __BINARYSEARCHTREE__
#include "BinaryTreeNode.h"
using namespace std;
class BinarySearchTree {
public:
BinarySearchTree();
~BinarySearchTree();
void insert(int);
private:
BinaryTreeNode *root;
void insert(int, BinaryTreeNode * & n);
};
#endif /* __BINARYSEARCHTREE__ */
#include "BinarySearchTree.h"
#include <iostream>
using namespace std;
BinarySearchTree::BinarySearchTree(){}
void BinarySearchTree::insert(int element)
{
insert(element, this->root);
}
void BinarySearchTree::insert(int element, BinaryTreeNode* & n)
{
if (n == 0)
{
n = new BinaryTreeNode(element);
}
else if (n->element > element)
{
insert(element, n->left);
}
else if (n->element < element)
{
insert(element, n->right);
}
}
EDIT -- Answered below, missed the angled braces. Thanks all.
I have been attempting to write a rudimentary singly linked list, which I can use in other programs. I wish it to be able to work with built-in and user defined types, meaning it must be templated.
Due to this my node must also be templated, as I do not know the information it is going to store. I have written a node class as follows -
template <class T> class Node
{
T data; //the object information
Node* next; //pointer to the next node element
public:
//Methods omitted for brevity
};
My linked list class is implemented in a seperate class, and needs to instantiate a node when adding new nodes to the end of the list. I have implemented this as follows -
#include <iostream>
#include "Node.h"
using namespace std;
template <class T> class CustomLinkedList
{
Node<T> *head, *tail;
public:
CustomLinkedList()
{
head = NULL;
tail = NULL;
}
~CustomLinkedList()
{
}
//Method adds info to the end of the list
void add(T info)
{
if(head == NULL) //if our list is currently empty
{
head = new Node<T>; //Create new node of type T
head->setData(info);
tail = head;
}
else //if not empty add to the end and move the tail
{
Node* temp = new Node<T>;
temp->setData(info);
temp->setNextNull();
tail->setNext(temp);
tail = tail->getNext();
}
}
//print method omitted
};
I have set up a driver/test class as follows -
#include "CustomLinkedList.h"
using namespace std;
int main()
{
CustomLinkedList<int> firstList;
firstList.add(32);
firstList.printlist();
//Pause the program until input is received
int i;
cin >> i;
return 0;
}
I get an error upon compilation however - error C2955: 'Node' : use of class template requires template argument list - which points me to the following line of code in my add method -
Node* temp = new Node<T>;
I do not understand why this has no information about the type, since it was passed to linked list when created in my driver class. What should I be doing to pass the type information to Node?
Should I create a private node struct instead of a seperate class, and combine the methods of both classes in one file? I'm not certain this would overcome the problem, but I think it might. I would rather have seperate classes if possible though.
Thanks, Andrew.
While the answers have already been provided, I think I'll add my grain of salt.
When designing templates class, it is a good idea not to repeat the template arguments just about everywhere, just in case you wish to (one day) change a particular detail. In general, this is done by using typedefs.
template <class T>
class Node
{
public:
// bunch of types
typedef T value_type;
typedef T& reference_type;
typedef T const& const_reference_type;
typedef T* pointer_type;
typedef T const* const_pointer_type;
// From now on, T should never appear
private:
value_type m_value;
Node* m_next;
};
template <class T>
class List
{
// private, no need to expose implementation
typedef Node<T> node_type;
// From now on, T should never appear
typedef node_type* node_pointer;
public:
typedef typename node_type::value_type value_type;
typedef typename node_type::reference_type reference_type;
typedef typename node_type::const_reference_type const_reference_type;
// ...
void add(value_type info);
private:
node_pointer m_head, m_tail;
};
It is also better to define the methods outside of the class declaration, makes it is easier to read the interface.
template <class T>
void List<T>::add(value_type info)
{
if(head == NULL) //if our list is currently empty
{
head = new node_type;
head->setData(info);
tail = head;
}
else //if not empty add to the end and move the tail
{
Node* temp = new node_type;
temp->setData(info);
temp->setNextNull();
tail->setNext(temp);
tail = tail->getNext();
}
}
Now, a couple of remarks:
it would be more user friendly if List<T>::add was returning an iterator to the newly added objects, like insert methods do in the STL (and you could rename it insert too)
in the implementation of List<T>::add you assign memory to temp then perform a bunch of operations, if any throws, you have leaked memory
the setNextNull call should not be necessary: the constructor of Node should initialize all the data member to meaningfull values, included m_next
So here is a revised version:
template <class T>
Node<T>::Node(value_type info): m_value(info), m_next(NULL) {}
template <class T>
typename List<T>::iterator insert(value_type info)
{
if (m_head == NULL)
{
m_head = new node_type(info);
m_tail = m_head;
return iterator(m_tail);
}
else
{
m_tail.setNext(new node_type(info));
node_pointer temp = m_tail;
m_tail = temp.getNext();
return iterator(temp);
}
}
Note how the simple fact of using a proper constructor improves our exception safety: if ever anything throw during the constructor, new is required not to allocate any memory, thus nothing is leaked and we have not performed any operation yet. Our List<T>::insert method is now resilient.
Final question:
Usual insert methods of single linked lists insert at the beginning, because it's easier:
template <class T>
typename List<T>::iterator insert(value_type info)
{
m_head = new node_type(info, m_head); // if this throws, m_head is left unmodified
return iterator(m_head);
}
Are you sure you want to go with an insert at the end ? or did you do it this way because of the push_back method on traditional vectors and lists ?
Might wanna try
Node<T>* temp = new Node<T>;
Also, to get hints on how to design the list, you can of course look at std::list, although it can be a bit daunting at times.
You need:
Node<T> *temp = new Node<T>;
Might be worth a typedef NodeType = Node<T> in the CustomLinkedList class to prevent this problem from cropping up again.
That line should read
Node<T>* temp = new Node<T>;
Same for the next pointer in the Node class.
As said, the solution is
Node<T>* temp = new Node<T>;
... because Node itself is not a type, Node<T> is.
And you will need to specify the template parameter for the Node *temp in printlist also.
// file: main.cc
#include "linkedlist.h"
int main(int argc, char *argv[]) {
LinkedList<int> list;
for(int i = 1; i < 10; i++) list.add(i);
list.print();
}
// file: node.h
#ifndef _NODE_H
#define _NODE_H
template<typename T> class LinkedList;
template<typename T>class Node {
friend class LinkedList<T>;
public:
Node(T data = 0, Node<T> *next = 0)
: data(data), next(next)
{ /* vacio */ }
private:
T data;
Node<T> *next;
};
#endif//_NODE_H
// file: linkedlist.h
#ifndef _LINKEDLIST_H
#define _LINKEDLIST_H
#include <iostream>
using namespace std;
#include "node.h"
template<typename T> class LinkedList {
public:
LinkedList();
~LinkedList();
void add(T);
void print();
private:
Node<T> *head;
Node<T> *tail;
};
#endif//_LINKEDLIST_H
template<typename T>LinkedList<T>::LinkedList()
: head(0), tail(0)
{ /* empty */ }
template<typename T>LinkedList<T>::~LinkedList() {
if(head) {
Node<T> *p = head;
Node<T> *q = 0;
while(p) {
q = p;
p = p->next;
delete q;
}
cout << endl;
}
}
template<typename T>LinkedList<T>::void add(T info) {
if(head) {
tail->next = new Node<T>(info);
tail = tail->next;
} else {
head = tail = new Node<T>(info);
}
}
template<typename T>LinkedList<T>::void print() {
if(head) {
Node<T> *p = head;
while(p) {
cout << p->data << "-> ";
p = p->next;
}
cout << endl;
}
}
You Should add new node in this way
Node<T>* temp=new node<T>;
Hope you Solved :)
#include<iostream>
using namespace std;
template < class data > class node {
private :
data t;
node<data > *ptr;
public:
node() {
ptr = NULL;
}
data get_data() {
return t;
}
void set_data(data d) {
t = d;
}
void set_ptr(node<data > *p) {
ptr = p;
}
node * get_ptr() {
return ptr;
}
};
template <class data > node < data > * add_at_last(data d , node<data > *start) {
node< data > *temp , *p = start;
temp = new node<data>();
temp->set_data(d);
temp->set_ptr(NULL);
if(!start) {
start = temp;
return temp;
}
else {
while(p->get_ptr()) {
p = p->get_ptr();
}
p->set_ptr(temp);
}
}
template < class data > void display(node< data > *start) {
node< data > *temp;
temp = start;
while(temp != NULL) {
cout<<temp->get_data()<<" ";
temp = temp->get_ptr();
}
cout<<endl;
}
template <class data > node < data > * reverse_list(node<data > * start) {
node< data > *p = start , *q = NULL , *r = NULL;
while(p->get_ptr()) {
q = p;
p = p->get_ptr();
q->set_ptr(r);
r = q;
}
p->set_ptr(r);
return p;
}
int main() {
node < int > *start;
for(int i =0 ; i < 10 ; i ++) {
if(!i) {
start = add_at_last(i , start);
}
else {
add_at_last(i , start);
}
}
display(start);
start = reverse_list(start);
cout<<endl<<"reverse list is"<<endl<<endl;
display(start);
}