Queue using Array>>shifting elements after popping - c++

I'm trying to implement a queue using an array. Here is my code:
#include <iostream.h>
#define SIZE 5
class queue
{
int *Queue, front, rear;
public:
queue() {
Queue = new int[SIZE];
front = rear = -1;
}
void push() {
if (rear == (SIZE-1)) {
cout<<"\n Overflow!";
} else {
rear++;
cout<<"\n Enter element: ";
cin>>Queue[rear];
}
}
void pop() {
if (front == rear) {
cout<<"\n Underflow!";
} else {
cout<<"\nElement popped: "<<Queue[++front];
}
}
void display() {
if (front == rear) {
cout<<"\n Queue Empty";
} else {
for(int i = (front+1); i<=rear; i++) {
cout<<Queue[i]<<" ";
}
}
}
};
int main()
{
int choice;
queue q;
while(choice != 4)
{
cout<<"\n\n Enter your choice :"
<<"\n 1. Push an element into Queue."
<<"\n 2. Pop an element from Queue."
<<"\n 3. Display the Queue."
<<"\n 4. Exit the program.\n\n";
cin>>choice;
switch (choice) {
case 1:
q.push();
break;
case 2:
q.pop();
break;
case 3:
q.display();
break;
case 4:
break;
}
}
return 0;
}
The thing is that once the overflow is met, even after popping an element the rear remains the same and another element is not added when there is a vacant space where it can go.
The solution for this could be to shift every element one place ahead so that there is empty spot at the end but I am having trouble with the shift. Also, if I try inserting after popping 2-3 times before reaching overflow then it still gives overflow even when there are only 3 elements in the queue.
How can I solve this?

You never reset front or rear, they keep increasing forever.
the overlflow test is also wrong:
if (rear == (SIZE-1)) {
cout<<"\n Overflow!";
what you should be testing is if your are about to overwrite front. I think you will benefit from keeping just front and the number of elements N instead. Then overflow and underflow becomes N>SIZE and N==0 instead. Then just increase and decrease N as you pop and push. Keep front as it is but also keep it modulo SIZE.
Also, as written in a comment. No need to move around the data.

Implement a Circular Buffer to avoid the need to shift the whole data.

Related

Problem with display function inside circular queue

#include <stdio.h>
# define MAX 3
int queue[MAX]; // array declaration
int front=-1;
int rear=-1;
// function to insert an element in a circular queue
void enqueue(int element)
{
if(front==-1 && rear==-1) // condition to check queue is empty
{
front=0;
rear=0;
queue[rear]=element;
}
else if((rear+1)%MAX==front) // condition to check queue is full
{
printf("Queue is overflow..");
}
else
{
rear=(rear+1)%MAX; // rear is incremented
queue[rear]=element; // assigning a value to the queue at the rear position.
}
}
// function to delete the element from the queue
int dequeue()
{
if((front==-1) && (rear==-1)) // condition to check queue is empty
{
printf("\nQueue is underflow..");
}
else if(front==rear)
{
printf("\nThe dequeued element is %d", queue[front]);
front=-1;
rear=-1;
}
else
{
printf("\nThe dequeued element is %d", queue[front]);
front=(front+1)%MAX;
}
}
// function to display the elements of a queue
void display()
{
int i=front;
if(front==-1 && rear==-1)
{
printf("\n Queue is empty..");
}
else
{
printf("\nElements in a Queue are :");
while(i<=rear)
{
printf("%d,", queue[i]);
i=(i+1)%MAX;
}
}
}
int main()
{
int choice=1,x; // variables declaration
while(choice<4 && choice!=0) // while loop
{
printf("\nPress 1: Insert an element");
printf("\nPress 2: Delete an element");
printf("\nPress 3: Display the element");
printf("\nEnter your choice");
scanf("%d", &choice);
switch(choice)
{
case 1:
printf("Enter the element which is to be inserted");
scanf("%d", &x);
enqueue(x);
break;
case 2:
dequeue();
break;
case 3:
display();
}}
return 0;
}
I have problem with display function how can i print all element if rear can be in somecases less than front for example in this code i try to enqueue 3 elements 1,2,3 then dequeue two elements which i mean here 1,2 after that i try to enque two elements 1,2 again finaly when i try to display elements i get nothing so what is the perfect way to display queue elements
So... here's a working solution.
#include <stdio.h>
# define MAX 3
class CircularQueue
{
private:
int queue[MAX]; // array declaration
int front;
int rear;
public:
CircularQueue() :
front(-1),
rear(-1)
{ }
// function to insert an element in a circular queue
void enqueue(int element)
{
if(front==-1 && rear==-1) // condition to check queue is empty
{
front=0;
rear=0;
queue[rear]=element;
}
else if((rear+1)%MAX==front) // condition to check queue is full
{
printf("Queue is overflow..\n");
}
else
{
rear=(rear+1)%MAX; // rear is incremented
queue[rear]=element; // assigning a value to the queue at the rear position.
}
}
// function to delete the element from the queue
void dequeue()
{
if((front==-1) && (rear==-1)) // condition to check queue is empty
{
printf("Queue is underflow..\n");
}
else if(front==rear)
{
printf("The dequeued element is %d\n", queue[front]);
front=-1;
rear=-1;
}
else
{
printf("The dequeued element is %d\n", queue[front]);
front=(front+1)%MAX;
}
}
// function to display the elements of a queue
void display()
{
if(front==-1 && rear==-1)
printf("Queue is empty..\n");
else
{
printf("Elements in a Queue are: ");
int i=front;
do
{
if (i != front)
printf(",");
printf("%d", queue[i]);
i=(i+1)%MAX;
} while (i != (rear+1)%MAX);
printf("\n");
}
}
};
int main()
{
CircularQueue cq;
unsigned int choice=1; // variables declaration
while(choice<4 && choice!=0) // while loop
{
printf("Press 1: Insert an element\n");
printf("Press 2: Delete an element\n");
printf("Press 3: Display the element\n");
printf("Press any other number to exit\n");
printf("Enter your choice: ");
scanf("%d", &choice);
switch(choice)
{
case 1:
printf("Enter the element which is to be inserted: ");
int x;
scanf("%d", &x);
cq.enqueue(x);
break;
case 2:
cq.dequeue();
break;
case 3:
cq.display();
}
}
return 0;
}
I made a couple of changes to the output, see the positions of the \n. Its always good to give the next print statement a new line to write to if the current output is complete.
The biggest change, I put everything in a class. That way you don't have any global variables, which is to 99.999% a bad thing. Your code is very C like, so normally I would use std::cout as well and with std::vector you could easily make you buffer have arbitrary size.
Here's some output:
Press 1: Insert an element
Press 2: Delete an element
Press 3: Display the element
Press any other number to exit
Enter your choice: 1
Enter the element which is to be inserted: 2
Press 1: Insert an element
Press 2: Delete an element
Press 3: Display the element
Press any other number to exit
Enter your choice: 3
Elements in a Queue are: 2
Press 1: Insert an element
Press 2: Delete an element
Press 3: Display the element
Press any other number to exit
Enter your choice: 4
TL;DR version: The hard part of making a circular buffer is telling the full condition from the empty condition because they are both front == rear unless you take extra steps like tracking the size or maintaining a bool full; or preventing rear from catching up to front.
I like the latter approach because it makes for really simple code. I like writing simple code. You don't have to think as hard debugging it. You don't have to spend as much time writing it. You don't get bothered by the maintenance team supporting it. Simple code is only a problem when it's too simple and misses a case.
So I'm going for simple here.
Embedding comments where I feel it's appropriate because explanation is easier to understand when it's right up close to what it is explaining.
#include <stdio.h>
// made MAX one bigger
// If we waste a space in the queue the only time front can be the same as rear
// is if the queue is empty. No ambiguity. No special code for special cases or
// extra tracking variables to tell full from empty.
// All for the low, low price of one queue element.
# define MAX 4
// in full on c++ this would be constexpr int MAX = 4;
// In general avoid macros because they are really stupid. With a macro any
// token MAX will be replaced with 4 no matter how bad an idea it is. The
// resulting compiler errors get really weird.
// with a constexpr, the compiler will not substitute anything and will take
// context into account, giving much better diagnostics if you screw up
int queue[MAX]; // array declaration
// Don't comment the obvious stuff
// it just clutters up the code and makes you look... well..
// Hey, look! Dummy here needs a comment to rem'ber he's
// defining an array! HA HA HA HA HA!
// You've got better things to do than put up with smurf like that.
int front=0;
int rear=0;
// global variables suck. Because a global can be changed by anything at any
// time tracking errors is a pain in the neck. Every function could have
// unexpected side effects and needs to be examined while debugging.
// Plus because these variables are global and shared, you can only ever have
// ONE queue and EVERYBODY can use it.
// These variables and the queue-handling functions should be in a queue class,
// and there should be an instance of this class defined in main.
// helper functions to keep repetition down.
// Also a well-named helper makes what's happening brutally obvious to anyone
// reading the code
int advance(int pos)
{
return (pos+1)%MAX;
}
bool empty()
{
return front == rear;
}
bool full()
{
return front == advance(rear);
// because of the wasted space telling full from empty is dead easy
}
// function to insert an element in a circular queue
void enqueue(int element)
{
if(full()) // see? Much easer to read than if (front == (rear+1)%MAX)
// now we barely need to comment.
{
printf("Queue is overflow.\n");
}
else
{
queue[rear]=element;
rear = advance(rear);
}
}
// function to delete the element from the queue
void dequeue()
{
if(empty())
{
printf("Queue is underflow.\n");
}
else
{
printf("The dequeued element is %d\n", queue[front]);
front = advance(front);
}
}
// function to display the elements of a queue
void display()
{
if(empty())
{
printf("Queue is empty.");
}
else
{
int i = front;
printf("Elements in a Queue are :");
while(i!=rear)
{
printf("%d,", queue[i]);
i = advance(i);
}
}
printf("\n");
}
// test the logic in small chunks. Make sure the queue works perfectly before
// slapping in a menu system. If there's a bug, you don't have to ask if it's
// in the menu or in the queue because you're only testing one thing at a time
// when you know they both work separately, put 'em together and test again
// just to be on the safe side.
int main()
{
display();
enqueue(1);
display();
dequeue();
display();
enqueue(2);
display();
enqueue(3);
display();
enqueue(4);
display();
enqueue(5); // fail
display();
enqueue(6); // fail
display();
dequeue();
display();
dequeue();
display();
dequeue();
display();
dequeue(); // fail
display();
dequeue(); // fail
display();
return 0;
}

Insertion and deletion in a stack using linked list

The program is about insertion and deletion in a stack using ling lists.The push works fine but there is problem in the deletion the pop() function has some
error. Every time i try to delete something it gives infinite error with underflow. ie. the top pointer is always null.
#include<iostream>
#include<stdlib.h>
#include<process.h>
using namespace std;
struct node
{
int info;
node *next;
}*top,*save,*newptr,*ptr;
node *create_new_node(int);
void push(node*);
void pop();
void display(node*);
int main()
{
top=NULL;
int inf;
char ch='y';
while(ch=='y'||ch=='Y')
{
newptr=new node;
cout<<"\nEnter the info to be added in the beginning of the stack\n";
cin>>inf;
if(newptr==NULL)
cout<<"\nCannot create new node.ABORTING!!\n";
else
{
newptr=create_new_node(inf);
cout<<"\nPress enter to continue\n";
system("pause");
}
push(newptr);
cout<<"\nthe info has been inserted in the stack\n";
cout<<"\nThe stack now is\n";
display(newptr);
cout<<"\ndo you wish to add more elements to the stack.\nIf yes then
press y or else press n\n";
cin>>ch;
if(ch=='n'||ch=='N')
{
cout<<"\ndo you to delete elements from the stack\n";
cout<,"\nIf yes then press d else press n\n";
cin>>ch;
if(ch=='d'||ch=='D')
{
while(ch=='d'||ch=='D')
{
pop();
cout<<"\npress d to delete more elements y to add more
elements and n to exit\n";
cin>>ch;
}
}
}
}
delete(ptr);
delete(newptr);
delete(top);
delete(save);
return 0;
}
node* create_new_node(int n)
{
ptr=new node;
ptr->info=n;
ptr->next=NULL;
return ptr;
}
void push(node *np)
{
if(top==NULL)
top=np;
else
{
save=top;
top=np;
np->next=save;
}
}
void pop()
{
if(top==NULL)
cout<<"underflow";
else
{
ptr=top;
top=top->next;
delete ptr;
}
}
void display(node *np)
{
while(np!=NULL)
{
cout<<np->info<<"->";
np=np->next;
}
}
There are multiple bugs in the shown code.
Your main bug:
while(ch=='d'||ch=='D')
{
pop();
cout<<"\npress d to delete more elements y to add more elements and n to exit\n";
}
At this point, when ch is 'd' or 'D' execution will enter the while loop, of course. A call to pop() is made, which removes the topmost element from the stack, prints a message, and repeats the while loop.
At this point your program will make an important discovery that ch is still either 'd' or 'D'. Nothing has changed its value. A computer program always does exactly what you tell it to do, unfortunately, instead of what you think you want it to do. No matter how hard you look here, you will never find any code here that ever changes the value of ch. It will remain at its current value forever. And so the while loop runs again. And again. And again. Nothing ever changes the value of ch, at this point, so you have an infinite loop.
Additionally, in your main:
newptr=new node;
This pointer's value is later compared to NULL; and if not ... it gets completely overwritten by
newptr=create_new_node(inf);
This accomplishes absolutely nothing, except leaking memory. This code appears to be leftover junk, and should be cleaned up after fixing the faulty while loop logic.

Implementation of QUEUE using Array

Implementation of QUEUE using Array in C++
There seems to be some problem with the Dequeue function.
Instead of deleting from front, it is deleting from rear..
I am not able to figure out what is wrong.
Please help!
#include <iostream>
using namespace std;
#define MAX_SIZE 101
int A[MAX_SIZE];
int front=-1,rear=-1;
void Enq(int x)
{ if (rear==(MAX_SIZE-1))
{return;}
if (front==-1 && rear==-1)
{front=rear=0;}
else { rear=rear+1;}
A[rear]=x;
}
void Deq()
{ if (front == -1 && rear == -1)
{return;}
else if(front == rear)
{
front = rear = -1;
}
else
front++;
}
void Print()
{ cout<<"Queue is: ";
int count=(rear-front);
for(int i=0; i<=count; i++)
{ cout<<A[i]<<" ";
}
cout<<"\n";
}
int main()
{
Enq(2); Print();
Enq(3); Print();
Enq(5); Print();
Deq(); Print();
Deq(); Print();
Enq(24); Print();
return 0;
}
OUTPUT:
Success time: 0 memory: 3460 signal:0
Queue is: 2
Queue is: 2 3
Queue is: 2 3 5
Queue is: 2 3
Queue is: 2
Queue is: 2 3
You are showing count elements, which is calculated as:
int count=(rear-front);
When you make
front++
You will just show one less element. But you always start at the position 0.
for(int i=0; i<=count; i++)
{ cout<<A[i]<<" ";
}
Maybe you should start from "front" and go up to "front+count"?
Keep in mind, trough, this implementation never really deletes anything, and you can just call Enq() MAX_SIZE times, no matter how many times you call Deq().
EDIT: If you want to be able to reuse spaces, you may add the element at the "front-1" position, and then do front--, only if front is >0.
Use your front and rear variables:
for(int i=front; i<=rear; i++) { cout<<A[i]<<" ";}
I would implement it using pointers anyways.

menue driven program to perform the following queue operation using array en-queue, de-queue, count the number of elements and display in c++?

i need to make a C++ program for
menu driven program to perform the following queue operation using array en-queue, de-queue, count the number of elements and display in c++?
how to make this one ?
im very weak in c++ can anyone guide me or help me or link me to a complete program to study it and understand it?!!!
i tried but i coudnt do it so i really need help
is this right or not ?
#include<iostream.h>
#include<conio.h>
void push(int st[],int data,int &top); //declaring a push class
void disp(int st[],int &top); //declaring display class
int pop(int st[],int &top); //declaring a pop class
int flg=0;
int top=-1,tos=-1;
int st[50];
void push(int st[],int data,int &top) //push
{
if(top==50-1)
flg=0;
else
{
flg=1;
top++;
st[top]=data;
}
}
int pop(int st[],int &top) //pop
{
int pe;
if(top==-1)
{
pe=0;
flg=0;
}
else
{
flg=1;
pe=st[top];
top--;
}
return(pe);
}
void disp(int st[],int &top) //display
{
int i;
if(top==-1)
{
cout<<"\nStack is Empty";
}
else
{
for(i=top;i>=0;i--)
cout<<"\t"<<st[i];
}
}
void main()
{
int dt,opt; // declare varible
int q=0;
clrscr();
cout<<"\t\t\tStack operations";
cout<<"\n\n\tMain Menu.........";
cout<<"\n\n1.Push";
cout<<"\n\n2.Pop";
cout<<"\n\n3.Exit";
cout<<"\n\n4.display";
do // useing do while for to make choice and select any options
{
cout<<"\n\n\tEnter Your Choice 1-4:"; //entering your choice
cin>>opt;
switch(opt)
{
case 1:
cout<<"\nEnter the Element to be Push:";
cin>>dt;
push(st,dt,tos);
if(flg==1)
{
cout<<"the push is done";
if(tos==50-1)
cout<<"\nStack is Now Full";
}
else
cout<<"\nStack Overflow Insertion Not Possible";
break;
case 2:
dt=pop(st,tos);
if(flg==1)
{
cout<<"\n\tData Deleted From the Stack is:"<<dt;
cout<<"\n \t pop is done";
}
else
cout<<"\nStack Empty,Deletio Not Possible:";
break;
case 3:
q=1;
break;
default:
cout<<"\nWrong Choice Enter 1-3 Only";
case 4:
disp(st,tos);
break;
}
} while(q!=1);
}
There is a queue collection in the STL library which provides all of the functionality required above for you, if for some reason you are not allowed to use this then I suggest the following logic might be helpful
when an item is popped from the front of the queue all other items must be copied down 1 element, use a for loop for this
E.g
for (int index = 1; index < arraySize; index++)
{
if (item[index] == -1)
{
item[index-1] = -1;
break;
}
item[index - 1] = item[index];
}
when an element is deleted, all items that follow that item in the queue must be moved down 1 space, find the index of the element being deleted and use a for loop
E.g
for (int index = deletedItemIndex; index < arraySize; index++)
{
if (item[index] == -1)
break;
item[index] = item[index + 1];
}
when an item is added to the queue it is simply placed at the end of the queue, but not necessarily the end of the array (perhaps initialise all the array elements with -1 to start, that way you can easily test if you are at the end of the queue)

Implementing a simple queue using arrays

I don't know much about arrays and queues and stacks. I know how to implement a simple queue.
#include <iostream>
#include <queue>
using namespace std;
void main()
{
queue<char> queue1;
queue1.push('a');
queue1.push('b');
queue1.push('c');
queue1.push('d');
while(!queue1.empty())
{
cout << queue1.front();
queue1.pop();
cout << endl;
}
system("pause");
}
How can I implement a simple queue using an array?
If your queue is based on an array, then for efficiency's sake, I would recommend creating a bounded or "circular" queue, where the max-size of the queue is fixed, and you basically have a head and tail pointer that point to the "first" and "last" positions in the queue's array, and when the tail-pointer (or an index value) moves to a position "past" the end of the array, it actually moves back to the beginning of the array. An unbounded queue based on an array would be horribly inefficient, as you would need to keep reallocating memory each time you fill up the max-size of the array, and/or attempt to re-shuffle elements down the array when you remove the first element of the queue.
Using integral-type array indexes for head and tail rather than actual pointer types, along with a counter for determining the overall number of items in your queue, your enqueue and dequeue functions could look as simple as:
template<typename T>
bool queue<T>::enqueue(const T& item)
{
if (count == array_size)
return false;
array[tail] = item;
tail = (tail + 1) % array_size;
count++;
return true;
}
template<typename T>
bool queue<T>::dequeue(T& item)
{
if (!count)
return false;
item = array[head];
head = (head + 1) % array_size;
count--;
return true;
}
You can extend this concept to whatever other functions you'd like, i.e., if you'd rather have a separate functions like the STL uses for accessing the head of the queue and actually "removing" an element from the queue.
NOTE: While simulating an array(linear data storage) as a circular data storage and maintaining the properties of Queue, one cell will always be unused. Hence, the maximum capacity of array will be 5 for the array having 6 cells. The c++ code below is self explanatory. Also, see The Linked List Based Implementation of Queue.
/*Implementation of queue with basic operation using arrays */
#include<iostream>
using namespace std;
#define MAX 6 //to accomodate a maximum of 05 elements as 1 cell pointed by tail will always be vacant
void ENQUE(int key); // ~insertion
int DEQUEUE(); // ~deletion
void TRAVERSE();
bool isEmpty();
bool isFull ();
int Q[MAX], head=0, tail=0; /* Note: head is the side facing cashier and new person joins the queue at tail. So, from cashier point of view tail~rear and head~front.
Q -> [h ][][][][][][][][][][t]
Q -> [h,t][][][][][][][][][][] : initial configuration*/
int main(){
int choice,val,i;
char ch='y';
do{
cout<<"1. For Enqueue \n";
cout<<"2. For Dequeue \n";
cout<<"3. For Traverse \nYour Option : ";
cin>>choice;
switch(choice)
{
case 1 : // insertion
if( isFull() ){
cout<<"\nQueue Full !!!\n";
break;
}
cin>>val;
ENQUE(val);
TRAVERSE();
break;
case 2 : //deletion
if( isEmpty() ){
cout<<"\nQueue Empty !!!\n";
break;
}
cout<<"\nDeleted element from Queue : "<<DEQUEUE()<<endl;
TRAVERSE();
break;
case 3 : //traversal
if( isEmpty() ){
cout<<"\nQueue Empty !!!\n";
break;
}
TRAVERSE();
break;
default :
cout<<"Please choose 1/2/3 !!! \n";
}
cout<<"\nDo you want to continue(y/n):";
cin>>ch;
}while(ch=='y'||ch=='Y'); //end of do loop
return 0;
}
void ENQUE(int x){
Q[tail] = x;
tail =(tail+1)%MAX ; //OR tail = (tail==MAX) ? 0 : tail+1 ; */
}
int DEQUEUE(){
int temp =Q[head];
head =(head+1)%MAX ; //OR head = (head==MAX) ? 0 : head+1 ; */
return temp;
}
void TRAVERSE(){
int i; //simple case: Q -> [ ][ ][h7][8][9][5t][ ][ ][ ][ ][ ]
for(i=head; i!=tail; i=(i+1)% MAX) //complex case: Q -> [16][t][ ][ ][ ][h5][11][12][13][14][15]
cout<<Q[i]<<" ";
cout<<endl;
}
bool isEmpty(){
if(head == tail)
return true;
else
return false;
}
bool isFull(){
if( (tail == MAX-1 && head == 0) || (head == tail + 1) )
return true;
else
return false;
}
A video tutorial of the same can be seen here : Data structures: Array implementation of Queue