I am writing a c++ code to implement template queue, but when I run my code, I get wrong results, not the expected results, here is the header file and the main code.
queue.h
#include <iostream>
#pragma once
using namespace std;
typedef int Error_code;
#define SUCCESS 0
#define OVERFLOW -1
#define UNDERFLOW -2
template <class T>
class Node{
public:
T item;
Node * next;
Node(){item=0; next=NULL;}
Node(T n){item=n; next=NULL;}
};
template <class T>
class queue
{
protected:
Node *front, *rear;
int count;
public:
queue(){
cout<<"constructor \n";
count = 0;
front = rear = NULL;};
~queue(){Node<T> * p;
while(front != NULL)
{
p = front;
front = front->next;
delete p;
}};
bool isempty(){
//return count == 0;
if(front==NULL)
return true;
else
return false;
};
bool isfull(){return false;};
Error_code serve(){
Error_code outcome = SUCCESS;
Node<T> *p;
if(isempty()){
cout<<"empty queue\n";
outcome=UNDERFLOW;
}
else{
p=front;
front=front->next;
delete p;
count--;
}
return outcome;
} ;
Error_code retrieve(T &item){
Error_code outcome= SUCCESS;
if(isempty())
{ // front node is empty, queue is empty
//return false;
cout<<"empty queue\n";
outcome=UNDERFLOW;
}
return outcome;
};
Error_code append(T item){
Node<T> * n ;
n= new Node; // create node
n->item = item; // set node pointers
n->next = NULL;
if (isempty())
{
rear=front = n;
}
else
{
rear->next = n; // else place at rear
rear = n; // have rear point to new node
}
count++;
return SUCCESS;
};
};
main.cpp
#include "queue.h"
#include <iostream>
using namespace std;
int main()
{
queue<int> q;
queue<char> q2;
int x;
char y;
cout<<"the fisrt queue is :";
q.isempty()?cout<<"empty \n\n":cout<<"not empty \n\n";
cout<<"the second queue is :";
q2.isempty()?cout<<"empty \n\n":cout<<"not empty \n\n";
q.append(2);
q.append(3);
q.append(4);
q2.append('a');
q2.append('b');
q2.append('c');
q.retrieve(x);
cout<<x<<endl;
q.serve();
q.retrieve(x);
cout<<x<<endl;
q.serve();
q.retrieve(x);
cout<<x<<endl;
q.serve();
q2.retrieve(y);
cout<<y<<endl;
q2.serve();
q2.retrieve(y);
cout<<y<<endl;
q2.serve();
q2.retrieve(y);
cout<<y<<endl;
q2.serve();
q.retrieve(x);
q2.retrieve(y);
system("pause");
return 0;
}
I get these results:
constructor
constructor
the first queue is: empty
the second queue is: empty
-858993460
-858993460
-858993460
then it prints some symbols
empty queue
empty queue
Your retrieve function doesn't retrieve:
Error_code retrieve(T &item){
Error_code outcome= SUCCESS;
if(isempty())
{ // front node is empty, queue is empty
//return false;
cout<<"empty queue\n";
outcome=UNDERFLOW;
}else
{
// needs something like:
item = front->item;
}
return outcome;
};
Apart from the missing template arguments, it should work then.
Related
This code is for Implementing binary tree.
It consist of insertNode(function which inserts node in the tree) and levelOrder(function which traverse the binary tree at level order).
insertNode function works fine but while executing levelOrder it successfully displays the data but after that it stops working and displays program has stopped working.
I can't find where i am going wrong?
Thanks in advance{ : )
#include<iostream>
using namespace std;
struct Node
{
Node *left;
Node *right;
int data;
}*root;
struct Queue
{
Node *p[1000];
int index=-1;
Node *add(Node *ptr)
{
p[++index]=ptr;
return ptr;
}
Node *peek()
{
if(index==-1)
return NULL;
return p[0];
}
Node *pop()
{
if(index==-1)
return NULL;
Node *temp=p[0];
for(int i=0;i<index;i++)
p[i]=p[i+1];
index--;
return temp;
}
};
Node * createNode(int data)
{
Node *p=new Node();
p->data=data;
p->left=p->right=NULL;
return p;
}
///////Insertion Of Node////////
int insertNode(int val)
{
if(root==NULL)
{
root=createNode(val);
return val;
}
bool found=false;
Node *p;
Queue q;
q.add(root);
while(found==false)
{
Node *l=(q.peek())->left;
Node *r=(q.peek())->right;
if(l==NULL)
{
(q.peek())->left=createNode(val);
found=true;
return val;
}
else
q.add(l);
if(r==NULL)
{
q.peek()->right=createNode(val);
found=true;
return val;
}
else
q.add(r);
q.pop();
}
return val;
}
/////////Traversal's///////////
void levelOrder(Node *p)
{
if(p==NULL)
return;
Queue q;
q.add(p);
while(true)
{
cout<<q.peek()->data<<" ";
if(q.peek()->left!=NULL)
q.add(q.peek()->left);
if(q.peek()->right!=NULL)
q.add(q.peek()->right);
if(q.pop()==NULL)
return;
}
}
int main()
{
root=NULL;
insertNode(1);
insertNode(2);
insertNode(3);
insertNode(4);
levelOrder(root);
return 0;
}
After you have popped the last element from the queue, you q.peek()->data on the next iteration, when q.peek() is not a valid pointer.
Change your termination condition:
while (q.peek())
{
cout<<q.peek()->data<<" "<< endl;;
if(q.peek()->left!=NULL)
q.add(q.peek()->left);
if(q.peek()->right!=NULL)
q.add(q.peek()->right);
q.pop();
}
On a side note, this is one situation where a "loop-local" variable can improve readability - all those peeks add clutter:
while(Node *next = q.pop())
{
cout<<next->data<<" "<< endl;;
if(next->left != nullptr)
q.add(next->left);
if(next->right != nullptr)
q.add(next->right);
}
my problem is it's Process returned -1073741819. What shall i do to compile it faster?
#include "Queue.h"
#include <iostream>
Queue::Queue()
{
topPtr = NULL;
tailPtr = NULL;
}
bool Queue::isEmpty()
{
if(topPtr == NULL && tailPtr == NULL)
return true;
else
return false;
}
void Queue::enqueue(int data)
{
Node *newNodePtr = new Node;
newNodePtr->data = data;
if(topPtr == NULL)
{
topPtr = tailPtr = newNodePtr;
tailPtr->nextPtr = NULL;
}
else
{
tailPtr->nextPtr = newNodePtr;
tailPtr = newNodePtr;
tailPtr->nextPtr = NULL;
}
}
int Queue::dequeue()
{
if (isEmpty())
{
cout << "empty" <<endl;
}
else
{
int dataToReturn = topPtr->data;
Node *nodeToDeletePtr = topPtr;
dataToReturn = nodeToDeletePtr->nextPtr;
topPtr = topPtr->nextPtr;
delete nodeToDeletePtr;
return dataToReturn;
}
}
#ifndef QUEUE_H
#define QUEUE_H
struct Node
{
int data;
Node *nextPtr;
};
class Queue
{
public:
Queue();
void enqueue(int data);
int dequeue();
bool isEmpty();
private:
Node *topPtr;
Node *tailPtr;
};
#endif
#include <iostream>
#include <string.h>
#include <cstdlib>
#include "Queue.h"
using namespace std;
int main(int argc, char const *argv[])
{
Queue integers;
string seriesIntegers;
cout << "Enter integers: ";
getline(cin, seriesIntegers);
char *seriesIntegersCStr = new char[seriesIntegers.length() + 1];
strcpy(seriesIntegersCStr, seriesIntegers.c_str());
char *tokens = strtok(seriesIntegersCStr, " ");
while(tokens != NULL)
{
integers.enqueue(atoi(tokens));
tokens = strtok(NULL, " ");
}
while(!integers.isEmpty())
{
cout << " " << integers.dequeue() << "\n";
}
}
Among the things wrong:
You never reset tailPtr to null during a dequeue operation that emptied the queue.
Due to the first item, your isEmpty member was incorrectly reporting the queue still had data because one of the two conditions (tailPtr == nullptr) was not true, and therefore the queue wasn't "empty" even though it was.
Due to both of the items above, your while-loop in main ran off the end of the queue.
Your dequeue operation has a major control path that returns no value, though you promised in your declaration of returns-int that it would. At a minimum this should throw an exception; ideally it should not be allowed in the first place.
Queue should self-clean on destruction rather than leaking the node chain in a non-empty state.
As a course of adding a custom destructor to clean dynamic content, Queue should be rule-of-three compliant by either defining proper operations for copy-ctor and assignment operators, or specifying them as deleted (as I did below)
Fixing all of that, and a few other modifications, including entering the real world of modern C++ to utilize a string stream to read the integers rather than strtok and leaked memory as you were before, see the code below:
#include <iostream>
#include <sstream>
#include <string>
struct Node
{
int data;
Node *nextPtr;
Node(int val, Node *next = nullptr)
: data(val)
, nextPtr(next)
{
}
};
class Queue
{
public:
Queue();
virtual ~Queue();
Queue(const Queue&) = delete;
Queue& operator =(const Queue&) = delete;
void enqueue(int data);
int dequeue();
bool isEmpty() const;
private:
Node *topPtr;
Node *tailPtr;
};
Queue::Queue()
: topPtr(nullptr)
, tailPtr(nullptr)
{
}
Queue::~Queue()
{
while (topPtr)
dequeue();
}
bool Queue::isEmpty() const
{
return topPtr == nullptr;
}
void Queue::enqueue(int data)
{
Node *newNodePtr = new Node(data);
if (topPtr == NULL)
{
topPtr = newNodePtr;
}
else
{
tailPtr->nextPtr = newNodePtr;
}
tailPtr = newNodePtr;
}
int Queue::dequeue()
{
if (isEmpty())
{
throw std::runtime_error("'dequeue' called on an already-empty queue");
}
// get top data
int dataToReturn = topPtr->data;
// advance top, retaining pointer to old node
Node *tmp = topPtr;
topPtr = topPtr->nextPtr;
// now delete the node
delete tmp;
// and reset tail if top hit end-of-queue
if (topPtr == nullptr)
tailPtr = nullptr;
// finally, return data
return dataToReturn;
}
int main()
{
std::cout << "Enter integers: ";
std::string line;
if (getline(std::cin, line) && !line.empty())
{
Queue integers;
std::istringstream iss(line);
int value;
while (iss >> value)
integers.enqueue(value);
while (!integers.isEmpty())
std::cout << integers.dequeue() << '\n';
}
}
Input
1 2 3 4 5
Output
Enter integers: 1 2 3 4 5
1
2
3
4
5
In this queue is implemented using Linked List, So the display function is showing the correct result but the SizeOf() is also implemented by the same logic and if called not showing the proper answer.
Why is this happening?
// A C program to demonstrate linked list based implementation of queue
#include <stdlib.h>
#include <stdio.h>
#include<bits/stdc++.h>
using namespace std;
// A linked list (LL) node to store a queue entry
struct QNode
{
int key;
struct QNode *next;
};
// The queue, front stores the front node of LL and rear stores the last node of LL
struct Queue
{
struct QNode *front, *rear;
};
// A utility function to create a new linked list node.
struct QNode* newNode(int k)
{
struct QNode *temp = (struct QNode*)malloc(sizeof(struct QNode));
temp->key = k;
temp->next = NULL;
return temp;
}
// A utility function to create an empty queue
struct Queue *createQueue()
{
struct Queue *q = (struct Queue*)malloc(sizeof(struct Queue));
q->front = q->rear = NULL;
return q;
}
// The function to add a key k to q
void enQueue(struct Queue *q, int k)
{
// Create a new LL node
struct QNode *temp = newNode(k);
// If queue is empty, then new node is front and rear both
if (q->rear == NULL)
{
q->front = q->rear = temp;
return;
}
// Add the new node at the end of queue and change rear
q->rear->next = temp;
q->rear = temp;
}
// Function to remove a key from given queue q
struct QNode *deQueue(struct Queue *q)
{
// If queue is empty, return NULL.
if (q->front == NULL)
return NULL;
// Store previous front and move front one node ahead
struct QNode *temp = q->front;
q->front = q->front->next;
// If front becomes NULL, then change rear also as NULL
if (q->front == NULL)
q->rear = NULL;
return temp;
}
void Display(struct Queue *q)
{
if(q==NULL)
{
cout<<"No elements"<<endl;
return;
}
else{
while(q->front->next!=NULL)
{
cout<<q->front->key<<" ";
q->front=q->front->next;
}
cout<<q->front->key<<" ";
}
}
int SizeOf(struct Queue *q)
{
int count=0;
if(q==NULL)
{
cout<<"No elements"<<endl;
return 0;
}
else{
while(q->front->next!=NULL)
{
count++;
q->front=q->front->next;
}
count++;
}
return count;
}
// Driver Program to test anove functions
int main()
{
struct Queue *q = createQueue();
enQueue(q, 10);
enQueue(q, 20);
deQueue(q);
deQueue(q);
enQueue(q, 30);
enQueue(q, 40);
enQueue(q, 50);
enQueue(q, 40);
enQueue(q, 50);
struct QNode *n = deQueue(q);
if (n != NULL)
printf("Dequeued item is %d\n", n->key);
cout<<"The Queue is Displayed as follows:"<<endl;
Display(q);
cout<<"The Queue Size is as follows:"<<endl;
int no=SizeOf(q);
cout<<no<<endl;`enter code here`
return 0;
}
Output of Display() is 40 50 40 50 but output of SizeOf() is 1. What is the problem with that?
I am new to C++. I am trying to do an exercise where I supposed to read postfix operations into a queue and then evaluate it using stack. In my file every line includes only one postfix operation and all operations thus lines ends with #. But I couldn't make the reading part. My function for that only does it job for 2 times but it needs to do 3 times.
Here is what I managed to write so far:
//queue cpp file
#include<iostream>
#include <cassert>
#include "Queue.h"
#include "stdlib.h"
using namespace std;
Queue::Queue(){
Size = 0;
head = NULL;
rear = NULL;
}
Queue::~Queue(){
Node* curPtr = head;
while( curPtr != 0 ) {
Node* nex = curPtr->next;
delete curPtr;
curPtr = nex;
}
head = 0;
}
bool Queue::empty() const {
if(Size==0){
return true;
}
return false;
}
int Queue::size() const {
return Size;
}
void Queue::enqueue(ElementType x){
Node *newNode = new Node;
newNode->data = x;
if(Size == 0){
rear=head = newNode;
Size++;
}
else{
rear->next=newNode;
rear=rear->next;
Size++;
}
}
void Queue::dequeue(){
Node * newNode;
if(Size==1){
newNode=head;
rear=NULL;
head=NULL;
delete newNode;
}
else{
newNode=head;
head=head->next;
delete newNode;
}
Size--;
}
ElementType Queue::front(){
return head->data;
}
//queue .h file
#ifndef QUEUE
#define QUEUE
using namespace std;
typedef string ElementType; // type of item to be stored
class Queue{
public:
int size() const; //return the number of elements in the queue
bool empty() const; //return true if queue is empty, else return false
void enqueue(ElementType x); //add x to the queue, increasing size()
void dequeue(); //remove the element most recently added to the queue, decreasing size()
ElementType front(); //return the element most recently added to the queue
Queue();
~Queue();
private:
class Node{
public:
ElementType data;
Node * next;
};
Node * head;
Node * rear;
int Size;
};
#endif
// stack cpp file
#include<iostream>
#include <cassert>
#include "Stack.h"
#include "stdlib.h"
using namespace std;
Stack::Stack(){
Size = 0;
head = NULL;
}
Stack::~Stack(){
cout << "destructor called2" <<endl;
Node* deleter;
deleter=head;
Node* temp;
while(deleter!=NULL){
temp=deleter;
deleter=deleter->next;
delete temp;
}
}
bool Stack::empty() const {
if(Size==0){
return true;
}
return false;
}
int Stack::size() const {
return Size;
}
void Stack::push(ItemType x){
Node *newNode = new Node;
newNode->data = x;
if(Size == 0){
head = newNode;
Size++;
}
else{
newNode->next = head;
head = newNode;
Size++;
}
}
void Stack::pop(){
Node *newNode;
if(Size==1){
newNode=head;
head=NULL;
delete newNode;
}
else{
newNode=head;
head=head->next;
delete newNode;
}
Size--;
}
ItemType Stack::top(){
return head->data;
}
// stack .h file
#ifndef STACK
#define STACK
#include<iostream>
using namespace std;
typedef int ItemType; // type of item to be stored
class Stack{
public:
Stack();
~Stack();
int size() const; //return the number of elements in the stack
bool empty() const; //return true if stack is empty, else return false
void push(ItemType x); //add x to the stack, increasing size()
void pop(); //remove the element most recently added to the stack, decreasing size()
ItemType top(); //return the element most recently added to the stack
private:
class Node{
public:
ItemType data;
Node * next;
};
Node * head;
int Size;
};
#endif
//test .cpp file where operations happen and main is
#include "Stack.h"
#include "Queue.h"
#include <stdio.h>
#include <iostream>
#include <string>
#include <sstream>
#include <fstream>
using namespace std;
void operatorAndWriter(Queue& k, Stack &l, ofstream &myfile);
void reader(Queue &loko, Stack &l);
int main(){
Stack l;
Queue at;
reader(at, l);
return 0;
}
void reader(Queue &loko, Stack &l){
cout << "Enter the file name : " << endl;
string filename;
cin >> filename;
ifstream meinfile (filename);
string line;
string sub;
ofstream myfile("example.txt");
while (! meinfile.eof()){
getline (meinfile, line);
istringstream iss(line);
while (iss >> sub){
loko.enqueue(sub);
}
operatorAndWriter(loko, l, myfile);
meinfile.close();
}
myfile.close();
}
void operatorAndWriter(Queue &k, Stack &l, ofstream &myfile){
if(myfile.is_open()){
while (k.size()!=0){
string op = k.front();
if (op == "+"){
int a = l.top();
l.pop();
int b = l.top();
l.pop();
l.push(a+b);
myfile << "+ ";
}
else if (op == "-"){
int a = l.top();
l.pop();
int b = l.top();
l.pop();
l.push(b-a);
myfile << "- ";
}
else if (op == "*"){
int a = l.top();
l.pop();
int b = l.top();
l.pop();
l.push(a*b);
myfile << "* ";
}
else if (op == "#"){
myfile << "# " ;
myfile << l.top() << endl;
l.pop();
}
else{
int y;
y=atoi(op.c_str());
l.push(y);
myfile <<l.top()<<" ";
}
k.dequeue();
}
}
}
// here is the input file
23 4 * 19 2 - + #
6 3 - #
36 #
// here is my example file which i tried create and write operations and their solutions in it. however there is just one solution which belongs to the first sentence of the a.txt file.
23 4 * 19 2 - + # 109
This is really a lot of code. First some stylistic advice:
Use nullptr instead of NULL.
2. you should check if the File actually exists so you don't corrupt your memory by accident.
3. Simplify your code, and only post the important part.
4. Include guards should end with _H
Now to your problem:
I didn't read all of your code but first of all you can simplify your reading function by writing something like this:
ifstream meinfile ("input.txt",ios::in);
while (getline (meinfile,line)){
// Use line here
}
I don't know if this will help, but is a lot of code after all.
I have to write code to implement template queue
I get this error : cannot access private member declared in class
at this line
front=front->next;
this is the header file of my code where I get the error:
#include <iostream>
#pragma once
using namespace std;
typedef int Error_code;
#define SUCCESS 0
#define OVERFLOW -1
#define UNDERFLOW -2
template <class T>
class Node{
T item;
Node * next;
Node(){item=0; next=NULL;}
Node(T n){item=n; next=NULL:}
};
template <class T>
class queue
{
protected:
Node<T>* front; // pointer to front of Queue
Node<T> * rear; // pointer to rear of Queue
int count; // current number of items in Queue
public:
queue();
~queue();
bool isempty(){
//return count == 0;
if(front==NULL)
return true;
else
return false;
};
bool isfull(){return false;};
Error_code serve(){
Error_code outcome = SUCCESS;
Node<T> *p;
if(isempty()){
cout<<"empty queue";
outcome=UNDERFLOW;
}
else{
p=front;
front=front->next;
delete p;
count--;
}
return outcome;
} ;
Error_code retrieve(T &item){
Error_code outcome SUCCESS;
if(isempty())
{ // front node is empty, queue is empty
//return false;
cout<<"empty queue";
outcome=UNDERFLOW;
}
return outcome;
};
Error_code append(T item){
Node<T> * n ;
n= new Node; // create node
n->item = item; // set node pointers
n->next = NULL;
if (isempty())
{
rear=front = n;
}
else
{
rear->next = n; // else place at rear
rear = n; // have rear point to new node
}
count++;
return SUCCESS;
};
};
front is a pointer to Node, but next is a private member in Node
template <class T>
class Node{
T item; // since you didn't specify access level
Node * next; // explicitly the access is private by default
Node(){item=0; next=NULL;}
Node(T n){item=n; next=NULL:}
};
so you cannot use it in queue class:
front=front->next; // error
change it to be public or redesign the program