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.
Related
In this code I just want to visit the node and count the edges. For the 1st time it seems good but when I pass new nodes and edges it is giving 0 count. I find out that it's condition is not true for the next nodes and edges. It's my first implementation of BFS.
#include<bits/stdc++.h>
using namespace std;
vector<int>v[1000];
int level[1000];
bool vis[1000];
void bfs(int s,int E)
{
int count=0;
queue<int>q;
q.push(s);
level[s]=0;
vis[s]=true;
while(!q.empty())
{
int p=q.front();
q.pop();
for(int i=0;i<v[p].size();i++)
{
if(vis[v[p][i]] == false)
{
level[v[p][i]] = level[p]+1;
q.push(v[p][i]);
vis[v[p][i]] = true;
count++;
}
}
}
cout<<count<<endl;
}
int main()
{
int N,E,x,y,size;
while(scanf("%d %d",&N,&E)==2)
{
for(int i=1;i<=E;i++)
{
scanf("%d %d",&x,&y);
v[x].push_back(y);
v[y].push_back(x);
}
int s=0;
bfs(s);
}
return 0;
}
You are not resetting whatever variables you have used like your adjacency list v,level and vis.
You have to reset them to some default value before working on a different graph, as values of previous graphs are unwanted.
You can simply run a loop, before each input:
for(int i=0;i<N;i++)
{
v[i].clear();
vis[i]=0;
level[i]=-1;
}
I was trying to implementing dfs to print paths from starting node . I followed algorithm from Coremen 's book . Here is my code :
DFS
#include<iostream>
#include<stack>
using namespace std;
int vertex,edge,source,time,adjacency_matrix[100][100],parent[100],Distance[100],Finishing_time[100];
string color[100];
stack<int> result;
void inputGraph();
void initialize();
void doDFS();
void doDFSvisit(int);
void printPath();
//void printAll();
//void printAdjacencyMatrix();
//void printColor();
//void printDistance();
//void printParent();
int main(void)
{
inputGraph();
//initialize();
doDFS();
printPath();
//printAll();
return 0;
}
void inputGraph()
{
cout<<"Total vertex : ";
cin>>vertex;
cout<<"Total edge : ";
cin>>edge;
int i,j;
for(i=1; i<=edge; i++)
{
int start,finish;
cout<<"Enter start and end node for edge "<<i<<" : ";
cin>>start;
cin>>finish;
adjacency_matrix[start][finish]=1;
}
cout<<"The adjacency matrix is : "<<endl;
for(i=1; i<=vertex; i++)
{
for(j=1; j<=vertex; j++)
{
cout<<adjacency_matrix[i][j]<<" ";
}
cout<<endl;
}
}
void initialize()
{
cout<<"Enter source node : ";
cin>>source;
}
void doDFS()
{
int i,j;
for(i=1;i<=vertex;i++)
{
color[i]="white";
parent[i]=0;
}
time=0;
for(i=1;i<=vertex;i++)
{
if(color[i]=="white")
{
doDFSvisit(i);
}
}
}
void doDFSvisit(int node)
{
int i;
time=time+1;
Distance[node]=time;
color[node]="grey";
for(i=1;i<=vertex;i++)
{
if(adjacency_matrix[node][i]==1)
{
if(color[i]=="white")
{
parent[i]=node;
doDFSvisit(i);
}
}
}
color[node]="black";
//extra line for result
result.push(node);
//
time=time+1;
Finishing_time[node]=time;
}
void printPath()
{
cout<<"Path :"<<endl;
int i;
for(i=0;i<=result.size();i++)
{
cout<<result.top()<<" -> ";
result.pop();
}
cout<<" End"<<endl;
}
My problem :
for input :
6
6
1 2
1 4
2 3
3 4
5 3
5 6
my output should be :
5 6 1 2 3 4 end
but my output is :
5 6 1 2 end
it seems printing values from stacks creates problem . please correct me where i did mistake , Thanks in advance .
[ P.S. : Pic of the directed graph that I used for input , http://imgur.com/fYsICiQ ]
There is mistake in the print_path function.
Your for-loop termination condition checks result(stack)'s size which decrements each loop-iteration by pop calling.
Your print_path function should look like something like this:
void printPath(){
cout<<"Path :"<<endl;
int i;
while(!result.empty()){
cout << result.top() << " -> ";
result.pop();
}
cout<<" End"<<endl;
}
Additionally consider this DFS implementation:
list<size_t> l[N];
bool used[N];
void DFS(size_t s){
if (used[s])
return;
used[s] = true;
for(auto i = l[s].begin(); i != l[s].end(); i++)
if(!used[*i]){
DFS(*i);
}
}
used is global bool array indicating i'th vertex is visited or not. We have no need to color vertexes. We have to know is it already visited or not.
l is adjacency list (see http://www.geeksforgeeks.org/graph-and-its-representations/ )
We run DFS on some vertex.
If it's visited we do nothing.
Else we mark this vertex as visited. And then go deeper running DFS on each vertex adjacent current vertex.
For more information about DFS see https://en.wikipedia.org/wiki/Depth-first_search
Here's how I would implement DFS in C++. First some observations:
I'll use adjacency lists (std::vectors) rather than an adjacency matrix.
Nodes aren't owned by their neighbors. They're assumed to be owned by a parent Graph object.
So, without further ado:
struct Node {
std::vector<Node *> neighbors;
// Other fields may go here.
}
void process(Node * node)
{
// Actual logic for processing a single node.
}
// Of course, in idiomatic C++, this would be a template
// parameterized by a function object, rather than contain
// a hard-coded call to a fixed `process` function.
void depth_first(Node * start)
{
std::stack <Node *> pending = { start };
std::unordered_set<Node *> visited;
while (!pending.empty()) {
Node * current = pending.pop();
process(current);
for (Node * neighbor : current->neighbors)
if (visited.find(neighbor) == visited.end()) {
pending.push (neighbor);
visited.insert(neighbor);
}
}
}
A nice thing about this implementation is that, in order to get BFS, you only need to replace std::stack with std::queue, and leave the rest of the code exactly as is.
I just wrote a code to build a Huffman Tree using MinHeap. When testing I want to output its traversal result.
The algorithm is simple, but my code can't get the right answer. It's strange that the output was different when I set different breakpoints. For instance, it depends on if I set a break point in the loop, such as line 165 input_list.insert(*parent);.
The test input was
4 //number of nodes.
1 1 3 5 //weight of each node.
and the output when debugging it with a breakpoint in the loop is
5
10
1
2
1
5
3
that is correct. But when I just run it without debug, it even didn't have any output. Does anyone know how to explain it?
#include <iostream>
#include <vector>
using namespace std;
#define max_size 100
int sum=0;
class huffman_node
{
public:
int weight;
huffman_node* left_child;
huffman_node* right_child;
huffman_node(){}
huffman_node(int w, huffman_node* l, huffman_node* r):
weight(w),left_child(l),right_child(r) {}
};
vector <huffman_node> node_list;
class minheap
{
public:
minheap()
{
heap=new huffman_node [max_size];
current_size=0;
}
~minheap()
{
delete []heap;
}
void siftdown(int start, int m)
{
int i=start;
int j=2*i+1;
huffman_node temp=heap[i];
while(j<=m)
{
if(j<m && heap[j+1].weight<heap[j].weight)
{
++j;
}
if(temp.weight<=heap[j].weight)
{
break;
}
else
{
heap[i]=heap[j];
i=j;
j=2*i+1;
}
}
heap[i]=temp;
}
void siftup(int start)
{
int j=start;
int i=(j-1)/2;
huffman_node temp=heap[j];
while(j>0)
{
if(heap[i].weight<=temp.weight)
{
break;
}
else
{
heap[j]=heap[i];
j=i;
i=(j-1)/2;
}
heap[j]=temp;
}
}
bool insert(const huffman_node& input)
{
if(current_size==max_size)
{
cout<<"minheap full"<<endl;
return false;
}
heap[current_size]=input;
siftup(current_size);
++current_size;
return true;
}
bool remove_min(huffman_node& output)
{
if(!current_size)
{
cout<<"minheap empty"<<endl;
return false;
}
output=heap[0];
heap[0]=heap[current_size-1];
--current_size;
siftdown(0,current_size-1);
return true;
}
private:
huffman_node* heap;
int current_size;
};
void route_length(huffman_node* &root,int depth)
{
if(root!=NULL)
{
// if(root->left_child==NULL&&root->right_child==NULL)
// {
// sum+=depth*root->weight;
// }
route_length(root->left_child,depth+1);
cout<<root->weight<<endl;
route_length(root->right_child,depth+1);
}
else
{
return;
}
}
int main()
{
minheap input_list;
int n;
cin>>n;
for(int i=0;i<n;++i)
{
int key;
cin>>key;
huffman_node input(key,NULL,NULL);
input_list.insert(input);
cin.get();
}
huffman_node* root;
for(int i=0;i<n-1;++i)
{
huffman_node* parent;
huffman_node out1;
huffman_node out2;
input_list.remove_min(out1);
input_list.remove_min(out2);
node_list.push_back(out1);
node_list.push_back(out2);
parent=new huffman_node(out1.weight+out2.weight,&node_list[node_list.size()-2],&node_list[node_list.size()-1]);
input_list.insert(*parent);
root=parent;
}
route_length(root,0);
// cout<<sum<<endl;
return 0;
}
The problem is that you are using pointers to elements of a vector<huffman_node> and storing these in your data structure (i.e. left and right members of the huffman_node object).
The thing that is randomly killing your program is that std::vector moves values around in memory when you append to it. The contents of the elements of the vectors are preserved, but the location is not. Once it moves the elements, the memory where the vector used to be can be overwritten by whatever (i.e. gdb needs heap memory too) and now the pointers are pointing to garbage.
As a quick sanity check, you can make your code not crash by reserving space in your node_list by calling
node_list.reserve(max_size*2);
in the beginning of main. This is not the right way of developing this piece of code further, but should illustrate the problem.
It would be better if your node_list was a vector<huffman_node*> instead. Or if you changed the left/right members to be vector indices instead of pointers.
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)
I'm trying to implement a queue with two stacks for purposes of understanding both data structures a little better. I have the below, with the main function serving as a test:
#include <iostream>
#include <stack>
using namespace std;
template <class T>
class _Stack : public stack<T> {
public:
T pop(){
T tmp=stack::top();
stack::pop();
return tmp;
}
};
template <class T>
class QueueS {
public:
QueueS(){}
bool isEmpty() const{
return pool.empty();
}
void enqueue(const T& el){
while( !output.empty()) {
input.push(output.pop());
}
input.push(el);
}
T dequeue(){
while(!input.empty()){
output.push(input.pop());
}
return output.pop();
}
T firstElement(){
if(output.empty()) {
return NULL;
}
return output.top();
}
private:
_Stack<T> pool;
_Stack<T> input;
_Stack<T> output;
};
int main(){
QueueS<int> n_QueueS;
//fill the queue of integers 0-9
for(int i=0; i<10;i++)
n_QueueS.enqueue(i);
// add another number to the queue
n_QueueS.enqueue(50);
//retrieve the first element without removing it
cout<<"front of the queue: "<<n_QueueS.firstElement()<<endl;
// removing the first 5 elements from the queue
cout<<"deleting first five elements of the queue: ";
for(int i=0; i<5;i++)
cout<<n_QueueS.dequeue()<<" ";
//removing the remainder of the queue and displaying the result
//should see 5 6 7 8 9 50 - see nothing!
cout<<endl<<"deleting remainder of the queue: ";
while(!n_QueueS.isEmpty())
cout<<n_QueueS.dequeue()<<" ";
if(n_QueueS.isEmpty())
cout<<endl<<"Queue is now empty";
else
cout<<endl<<"Error in emptying the queue";
system("pause");
return 0;
}
It works pretty well thusfar. However, when I run my test, deleting the first five elements works fine, and they display fine. It displays the line "deleting first five elements of the queue:" followed by 0 1 2 3 4, as expected.
However, deleting the second half doesn't display the values after the text "deleting remainder of the queue" like the previous test case did. I'm assuming the problem is minor, but I can't locate it through debugging. Maybe I've overlooked something?
Any help would be greatly appreciated!
First of all, your empty check should be something like this:
bool isEmpty() const{
return input.empty() && output.empty();
}
in enqueue, just push to the input stack:
void enqueue(const T& el){
input.push(el);
}
in enqueue and dequeue, move input to output if output is empty:
T dequeue(){
if (output.empty())
while(!input.empty()){
output.push(input.pop());
}
// throw exception of output.empty() ??
return output.pop();
}
T firstElement(){
if (output.empty())
while(!input.empty()){
output.push(input.pop());
}
if(output.empty()) {
return T(0); // throw exception?
}
return output.top();
}