Multi Server Queue Simulation C++ - c++

This assignment (I've linked the full description here) asks us to create a multi server queue simulation (i.e. grocery store type scenario). My code seems to be working for the most part however I currently have 2 questions pertaining to my output that I am having a hard time answering.
Why does queue_total not match the actual number of elements displayed in each queue at the end of the program?
Why won't new items be enqueued to the shortest queue even though the shortest_queue function seems to be working?
The main code:
#include <cstdlib>
#include <ctime>
#include <iostream>
#include <iomanip>
#include "queue_2.h"
using namespace std;
// Utility function to return shortest queue.
int shortest_queue(Queue line[], int queuecount)
{
int shortest = 0;
// Condition 1: If a queue is empty
// with no active transactions, return it.
for (int i = 0; i < queuecount; i++) {
if (line[i].empty() && line[i].get_trans_time() == 0)
return i;
}
// Condition 2: If a queue is simply empty,
// return it next.
for (int i = 0; i < queuecount; i++) {
if(line[i].empty()) {
return i;
}
}
// Condition 3: (otherwise) If all queues are
// occupied check for shortest queue.
for (int i = 1; i < queuecount; i++) {
if(line[i].size() < line[shortest].size())
shortest = i;
}
return shortest;
}
// Utility function to return total number
// of customers waiting in queues.
int queue_total(Queue q[], int queuecount)
{
int custcount = 0;
for (int i = 0; i < queuecount; ++i)
custcount += q[i].size();
return custcount;
}
int main()
{
// Variable decelrations
int trans_time = 0;
int count = 0;
int entry_time;
int wait_sum = 0;
int wait_time = 0;
int seed = 3;
int ariv_prob = 80;
int MAX_TRANS_TIME = 12;
int DURATION = 120;
int queuecount = 4;
int shortline;
int temp;
// Create a list of queues
// and random number generator
Queue line[queuecount];
srand(seed);
for (int time = 1; time < DURATION + 1; time++)
{
// Display the time
cout << "Time: " << time << endl;
// Check probablity only once per iteration
if ( rand() % 100 < ariv_prob ) {
shortline = shortest_queue(line, queuecount);
line[shortline].enqueue(time);
}
// Update the transaction times for
// the corresponding queues and compute
// summary statistics.
for (int i = 0; i < queuecount; i++) {
if ( line[i].get_trans_time() == 0 ) {
if ( !line[i].empty() ) {
entry_time = line[i].print_front();
line[i].dequeue();
temp = (time - entry_time);
if(temp > wait_time)
wait_time = temp;
wait_sum += (time - entry_time);
++count;
line[i].set_trans_time((rand() % MAX_TRANS_TIME) + 1);
}
}
// Decrement and update transaction time.
else {
trans_time = line[i].get_trans_time() - 1;
line[i].set_trans_time(trans_time);
}
}
// Display status of the queues for the
// the given iteration.
for (int i = 0; i < queuecount; i++) {
cout << setw(4) << line[i].get_trans_time() << " ";
line[i].display();
}
cout << endl;
}
cout << count << " customers waited an average of ";
cout << wait_sum / count << " ticks." << endl;
cout << "The longest time a customer waited was " << wait_time << " ticks." << endl;
cout << queue_total(line, queuecount) << " customers remain in the lines." << endl;
return 0;
}
The queue implementation
#ifndef QUEUE_H
#define QUEUE_H
#include <iostream>
using namespace std;
class Queue {
private:
struct Node {
int data;
Node* next;
Node(int d) {
data = d;
next = NULL;
}
};
Node* front;
Node* rear;
int count;
int trans_time;
public:
Queue() {
front = rear = NULL;
count = trans_time = 0;
}
void enqueue(int x) {
// Create a new linked Node.
Node* temp = new Node(x);
// If the queue is already empty
// then new node is front and rear
if (empty()) {
front = rear = temp;
return;
}
// Add the new node at the end
// of the queue and change the rear
rear->next = temp;
rear = temp;
++count;
}
void dequeue() {
// If the queue is empty
// then we can return NULL
if (empty())
return;
// Store the previous front and
// move the front one node ahead
Node* temp = front;
front = front->next;
// If front becomes NULL, then
// Change the rear to be NULL as well
if (front == NULL)
rear = NULL;
delete(temp);
--count;
}
// Utility function to check
// if the queue is empty
bool empty() {
return (front == NULL && rear == NULL);
}
int size() {
return count;
}
// Utility function to print front
// element of the queue
int print_front() {
return front->data;
}
void display() {
Node* temp = front;
while (!(temp == NULL)) {
cout << temp->data << " ";
temp = temp->next;
}
cout << endl;
}
void set_trans_time(int i) {
trans_time = i;
}
int get_trans_time() {
return trans_time;
}
};
#endif

Your enqueue function doesn't increment (or set) the count when inserting into an empty queue. This causes the count to be 0 for a queue with 1 element.
The comparisons for count > 0 or count >= 0 before decrementing/incrementing it should be unnecessary. If those conditions are ever false then you have a problem elsewhere that caused the inconsistency.

Related

Queue implementation and array resizing using C++

The code is supposed to do queue functions which I got right.
The only problem I am having is: I am supposed to double the array size to twice its original size once the array gets completely filled.
I have coded for it but still getting garbage values when I try to put in more values than the original array size. So the problem seems to be in the inc() function below:
#ifndef Q_H_
#define Q_H_
#include <iostream>
using namespace std;
template <class elemType>
class arrayQueue
{
int size;
int *array;
int front;
int back;
int count;
public:
arrayQueue(elemType size)
{
this->size = size;
array = new int[size];
front = 0;
back = -1;
count=0;
}
bool isEmpty()
{
return (max()==0);
}
bool isFull() {
return (max()==size);
}
void enqueue(elemType entry)
{
cout << "enqueue " << entry;
if(isEmpty())
{
front = back = 0;
array[back] = entry;
count++;
}
else
{
back = (back+1) % size;
array[back] = entry;
count++;
}
cout << endl;
}
int maxsize()
{
return count;
}
void dequeue() {
cout << "dequeue : " << Front();
if(isEmpty())
{
cout << " error : empty";
}
else if(back == front)
{
back = front = -1;
}
else
{
front = (front+1) % size;
count--;
}
cout << endl;
}
void print()
{
if(isEmpty())
{
cout << "Queue is empty";
}
else
{
for(int i = front; i<count; i++)
{
cout << array[i] << " ";
}
cout << array[back];
}
//cout<<"count is:" <<count<<endl;
cout << endl;
}
int Front()
{
if(front == -1)
{
cout<<"Queue is empty\n";
return -1;
}
return array[front];
}
int Back()
{
if(back==-1)
{
cout<<"Queue is full";
}
return array[back];
}
int max()
{
return count;
cout <<"count: " <<count;
}
void inc()
{
int newsize = this->size*2;
elemType *temp = new elemType[newsize];
for (int i=0; i<this->count;i++)
{
temp[i]=this->array[(front+i) % size];
}
delete [] this->array;
this->array=temp;
this->count=newsize;
// front=array[front]; //0
//front = 0;
//back=count;
}
};
#endif /* Q_H_ */
I would really appreciate help with this.
three small changes:
enqueue method: inc when isFull
if (isFull())
{
inc();
}
print method: print every element from front to back
inc method: copy every element from front to back, and reset front and back index
void inc()
{
int newsize = this->size*2;
elemType *temp = new elemType[newsize];
// ******* IMPORTANT ******
// copy count elements
for (int i = 0; i < count; ++i) {
int index = (front + i) % size;
temp[i] = array[index];
}
front = 0;
back = count - 1;
delete []array;
array=temp;
count=newsize;
}
template <class elemType>
class arrayQueue
{
int size;
int *array;
int front;
int back;
int count;
public:
arrayQueue(elemType size)
{
this->size = size;
array = new int[size];
front = 0;
back = -1;
count=0;
}
bool isEmpty()
{
return (max()==0);
}
bool isFull() {
return (max()==size);
}
void enqueue(elemType entry)
{
cout << "enqueue " << entry;
if(isEmpty())
{
front = back = 0;
array[back] = entry;
count++;
}
else
{
if (isFull()) {
inc();
}
back = (back+1) % size;
array[back] = entry;
count++;
}
cout << endl;
}
int maxsize()
{
return count;
}
void dequeue() {
cout << "dequeue : " << Front();
if(isEmpty())
{
cout << " error : empty";
}
else if(back == front)
{
back = front = -1;
}
else
{
front = (front+1) % size;
count--;
}
cout << endl;
}
void print()
{
if(isEmpty())
{
cout << "Queue is empty";
}
else
{
// ******* IMPORTANT ******
for (int i = 0; i < count; ++i) {
int index = (front + i) % size;
cout << array[index] << " ";
}
}
//cout<<"count is:" <<count<<endl;
cout << endl;
}
int Front()
{
if(front == -1)
{
cout<<"Queue is empty\n";
return -1;
}
return array[front];
}
int Back()
{
if(back==-1)
{
cout<<"Queue is full";
}
return array[back];
}
int max()
{
return count;
cout <<"count: " <<count;
}
void inc()
{
int newsize = this->size*2;
elemType *temp = new elemType[newsize];
// ******* IMPORTANT ******
// copy count elements
for (int i = 0; i < count; ++i) {
int index = (front + i) % size;
temp[i] = array[index];
}
front = 0;
back = count - 1;
delete []array;
array = temp;
count = newsize;
}
};
Since you move elements to the beginning of the newly allocated array, inc needs to update front and back to refer to their respective new positions.
Also, you're updating count to be the new size instead of size.

LinkedList Backtracking

I'm trying to backtrack through a linkedlist I have created to solve a knight's tour problem, but once I hit a condition requiring me to backtrack, it totally empties the list. I have figured out it is because when I return false from the function findpath() to keep my while loop going, it continually loops back through the goback() function. What I'm having trouble figuring out is why. When i go through the goback function and call the calcmove function, it pushes the correct move to the structure I have declared, so passing false should keep the loop going and restart with the boolean cando and figuring out if that is false or not. But, it should be true because I just tested it and pushed it to the stack. Instead, it's emptying the list after I backtrack for the first time. So calcmove() would just be returning false every time after the first pop. But I don't see why that's happening. I need to return false to keep the loop going. What I need it to do is go back only once, find a new move, and continue on. Why would it be looping back to the function where the value on the list gets popped? If the value worked, and a new move is created (which I did verify it is doing correctly), it should be ready to call with a new (true) boolean. Is this just an inherently bad way of implementing the backtracking?
#include "stdafx.h"
#include "Header.h"
#include <stdio.h>
#include <algorithm>
#include <iostream>
#include <iomanip>
llist list;
Move m;
int board[8][8];
int cx[] = { -2, -1, 1, 2, 2, 1, -2, -1 };
int cy[] = { 1, 2, 2, 1, -1, -2, -1, -2 };
int movenum = 1;
Move first;
/*Check to see if move is within the constraints of the board*/
bool constraints(int k, int b) {
if ((k < 0) || (b < 0) || (k > 7) || (b > 7) || (board[k][b] != -1)) {
return true;
}
else {
return false;
}
}
/* Initialization of 8x8 board, fill the array with -1 */
void initboard() {
for (int x = 0; x < 8; x++) {
for (int y = 0; y < 8; y++) {
board[x][y] = -1;
}
}
}
/* Output the current board array */
void printboard(int arr[8][8]) {
for (int x = 0; x < 8; x++) {
for (int y = 0; y < 8; y++) {
cout << std::setw(2) << arr[x][y] << " ";
}
cout << endl;
}
}
void updateboard(int k, int b) {
board[k][b] = movenum;
movenum++;
}
bool calcmove(int x, int y, int i) {
for (i; i < 9; i++) {
int a0 = x + cx[i];
int a1 = y + cy[i];
/*if(board[a0][a1] == board[first.x][first.y]){
}*/
if (constraints(a0, a1) == false) {
updateboard(a0, a1);
m.x = a0;
m.y = a1;
m.index = i;
list.push(m);
//list.display();
return true;
}
}
return false;
}
void goback(int k, int b) {
board[k][b] = -1;
list.display();
Move m = list.pop();
bool cando = calcmove(m.x, m.y, m.index);
cout << "prev is " << m.x << " , " << m.y << endl;
if (cando) {
return;
}
else {
goback(m.x,m.y);
}
}
bool findpath(){
bool cando = calcmove(m.x, m.y, 0);
if (cando) {
return false;
}
else {
movenum--;
goback(m.x, m.y);
return false; /*------> inserting this here drains the list*/
}
return true;
}
int main()
{
int m1 = 1;
int m2 = 2; //random
first.x = m1;
first.y = m2;
first.index = 0;
list.push(first); //push first node on to stack
initboard();
updateboard(m1, m2); //update board
while (!findpath()) {
;
}
printboard(board);
}
the .h file:
#include<iostream>
#include<cstdio>
#include<cstdlib>
#include <ostream>
using std::cout;
using std::endl;
using std::setw;
struct Move {
int x;
int y;
uint32_t index;
};
struct node
{
public:
Move info;
struct node *next;
};
class llist {
struct node *start;
public:
void push(Move coords) {
struct node *p = new node;
p = newnode(coords);
if (start == NULL) {
start = p;
}
else {
p->next = start;
start = p;
//cout << "pushed" << endl;
}
}
Move pop() {
if (start == NULL) {
throw std::runtime_error("The list is empty");
}
else {
struct node *temp = new node;
temp = start;
Move data = start->info;
start = start->next;
delete temp;
//cout << "pop successful" << endl;
return data;
}
}
node *newnode(Move value) {
struct node *temp = new(struct node);
if (temp == NULL) {
return 0;
}
else {
temp->info = value;
temp->next = NULL;
return temp;
}
}
void display()
{
struct node *temp;
if (start == NULL)
{
cout << "The List is Empty" << endl;
return;
}
temp = start;
cout << "Elements of list are: " << endl;
while (temp != NULL)
{
cout << temp->info.x << "->";
temp = temp->next;
}
cout << "empty" << endl;
}
};
The goal of this is to create a linked list, solve the problem using the list for backtracking (push the current move unless no moves are available, then pop the previous values), and return the completed board.

AVL Tree implementation c++

So I've posted about this recently, but I'm still at a loss for what is going wrong. Specifically, I can't seem to figure out what's causing my AVL Tree to take so long to sort. I read in a file of 500,000 random, unsorted numbers to sort by using a vector in a for loop to feed the tree the numbers one at a time. Now, I've also tested using a normal BST, as someone mentioned that having to create so many nodes one at a time might be why it's taking so long, but that completed in only 5 seconds, with only 12,164 nodes skipped due to being duplicates. My AVL Tree is taking upwards of 3 hours just to sort half the list, so something must be going wrong. Can anyone figure out what it is? As far as I know, the rebalancing and insertion logic is correct, because whenever I ran a bunch of test cases on it they all came out fine. I can't seem to track down where the problem is. Here's my full code for anyone that wants to check it out. Main is kind of a mess right now because of all the stuff I've included for testing purposes (like the tracking loop), but most of that will be gone in the final version.
EDIT:
This question has been answered.
#include <iostream>
#include<iomanip>
#include <time.h>
#include <vector>
#include <fstream>
using namespace std;
vector<int> numbers;
struct node
{
public:
int data, height;
node *leftChild, *rightChild;
};
node* root = NULL;
int findMin(node *p) // finds the smallest node in the tree
{
while (p->leftChild != NULL)
p = p->leftChild;
return p->data;
}
int findMax(node *p) // finds the largest node in the tree
{
while(p->rightChild != NULL)
p = p->rightChild;
return p->data;
}
int max(int a, int b) // gets the max of two integers
{
if(a > b)
return a;
else
return b;
}
int height(node *p) // gets the height of the tree
{
if(p == NULL)
return -1;
else
{
p->height = max(height(p->leftChild), height(p->rightChild)) + 1;
}
return p->height;
}
node* newNode(int element) // helper function to return a new node with empty subtrees
{
node* newPtr = new node;
newPtr->data = element;
newPtr->leftChild = NULL;
newPtr->rightChild = NULL;
newPtr->height = 1;
return newPtr;
}
node* rightRotate(node* p) // function to right rotate a tree rooted at p
{
node* child = p->leftChild; // rotate the tree
p->leftChild = child->rightChild;
child->rightChild = p;
// update the height for the nodes
p->height = height(p);
child->height = height(child);
// return new root
return child;
}
node* leftRotate(node* p) // function to left rotate a tree rooted at p
{
node* child = p->rightChild; // perform the rotation
p->rightChild = child->leftChild;
child->leftChild = p;
// update the heights for the nodes
p->height = height(p);
child->height = height(child);
// return new root
return child;
}
int getBalance(node *p)
{
if(p == NULL)
return 0;
else
return height(p->leftChild) - height(p->rightChild);
}
// recursive version of BST insert to insert the element in a sub tree rooted with root
// which returns new root of subtree
node* insert(node*& p, int element)
{
// perform the normal BST insertion
if(p == NULL) // if the tree is empty
return(newNode(element));
if(element < p->data)
{
p->leftChild = insert(p->leftChild, element);
}
else
{
p->rightChild = insert(p->rightChild, element);
}
// update the height for this node
p->height = height(p);
// get the balance factor to see if the tree is unbalanced
int balance = getBalance(p);
// the tree is unbalanced, there are 4 different types of rotation to make
// Single Right Rotation (Left Left Case)
if(balance > 1 && element < p->leftChild->data)
{
return rightRotate(p);
}
// Single Left Rotation (Right Right Case)
if(balance < -1 && element > p->rightChild->data)
{
return leftRotate(p);
}
// Left Right Rotation (double left rotation)
if(balance > 1 && element > p->leftChild->data)
{
p->leftChild = leftRotate(p->leftChild);
return rightRotate(p);
}
// Right Left Rotation
if(balance < -1 && element < p->rightChild->data)
{
p->rightChild = rightRotate(p->rightChild);
return leftRotate(p);
}
// cout << "Height: " << n->height << endl;
// return the unmodified root pointer in the case that the tree does not become unbalanced
return p;
}
void inorder(node *p)
{
if(p != NULL)
{
inorder(p->leftChild);
cout << p->data << ", ";
inorder(p->rightChild);
}
}
void preorder(node *p)
{
if(p != NULL)
{
cout << p->data << ", ";
preorder(p->leftChild);
preorder(p->rightChild);
}
}
void print(node* root)
{
/*cout << "Min Value: " << findMin(root) << endl;
cout << "Max Value: " << findMax(root) << endl;
cout << "Pre Order: ";
preorder(root); */
cout << endl << "Inorder: ";
inorder(root);
cout << endl << endl << endl << endl;
}
void read()
{
int num;
ifstream file_save("data.txt");
if(file_save.is_open())
{
while(!file_save.eof())
{
file_save >> num;
numbers.push_back(num);
}
file_save.close();
}
else
{
cout << "Error in opening file!!" << endl;
}
}
int main()
{
double duration;
time_t begin = time(0);
read();
int x = 0;
int track = 0;
for (std::vector<int>::const_iterator i = numbers.begin(); i != numbers.begin() + 100000; ++i)
{
root = insert(root, numbers[x]);
x++;
track++;
if( (track % 10000) == 0)
{
cout << track << " iterations" << endl;
time_t now = time(0);
cout << now - begin << " seconds" << endl;
}
}
time_t end = time(0);
duration = end - begin;
// print(root);
cout << "The algorithm took " << duration << " seconds to complete." << endl;
return 0;
}
There are many problems with this code.
while(eof) is wrong.
The main loop expects exactly 100000 elements.
All key comparisons are exact (<, >). There are no rotations performed when a duplicate element is inserted. Thus a tree of identical elements will not be balanced at all.
The height of an empty tree is hardcoded to -1, but the height of a single-node three is initially set to 1, thus violating the invariant height(node) = 1+max(height(node->leftChild))+height(node->rightChild)).
height traverses the entire tree every time it is called, thus making insertion O(n).
So, it seems to me that the reason that it was taking so long was because of too many recursive calls all over the place. This modified code has less recursive calls and thus bogs down the CPU with less stacks to have to process. At least, that's what I'm getting out of this.
void newHeight(node* p)
{
double leftHeight = height(p->leftChild);
double rightHeight = height(p->rightChild);
if(leftHeight > rightHeight)
p->height = leftHeight;
else
p->height = rightHeight;
}
node* rotateright(node* p) // the right rotation round p
{
node* q = p->leftChild;
p->leftChild = q->rightChild;
q->rightChild = p;
newHeight(p);
newHeight(q);
return q;
}
node* rotateleft(node* q) // the left rotation round q
{
node* p = q->rightChild;
q->rightChild = p->leftChild;
p->leftChild = q;
newHeight(q);
newHeight(p);
return p;
}
node* rebalance(node* p) // p node balance
{
newHeight(p);
if( getBalance(p)==2 )
{
if( getBalance(p->rightChild) < 0 )
p->rightChild = rotateright(p->rightChild);
return rotateleft(p);
}
if (getBalance(p)==-2 )
{
if( getBalance(p->leftChild) > 0 )
p->leftChild = rotateleft(p->leftChild);
return rotateright(p);
}
return p; // no balance needed
}
node* insert(node* p, int element) // k key insertion in the tree with p root
{
if(!p) return newNode(element);
if(element < p->data)
p->leftChild = insert(p->leftChild, element);
else
p->rightChild = insert(p->rightChild, element);
return rebalance(p);
}

Single Link List delete function in the middle issue

I look around for some help for single link list around the web but couldn't find the information I needed. What im trying to do is Design and Implement a single linked list with the following operations
a- Create "n" nodes
b- Delete from the middle (where im not deleting the middle, but anything else but the start and end node)
c- Insert in the middle
I did my "insert" part with a ADD function
but when I get to the delete function, im stuck in how to use a single link list & not a double, because Im trying to break that habit. Anyway here my code, it my delete function that im trying to fix. thanks
PS: tell me if my add function is also correct, :)
#include <iostream>
#include <vector>
using namespace std;
class node
{
public:
node(int user_input);
int info;
node * next_node;
};
node::node(int user_input)
{
info = user_input;
next_node = NULL;
}
class link_list
{
public:
node * start;
node * end;
int size;//seperated the attritibute from the method
link_list(); //default constuctor
link_list(int value); //value constuctor
link_list(int value, int num_of_Nodes); //n-ary
void Add(int store_node);
void Print(); //non midify
void insert_at_begining(int value); //while these guys are modify
void insert_at_end(int value); //
void insert_at_middle(int delete_node);
void delete_at_begining();
void delete_at_end(); //
void delete_at_middle(int Nodes_store);
private:
int Number_of_nodeV2;
};
link_list::link_list(int value, int num_of_Nodes) //this
{
//if val = 0 & num = 5 we get 5 new nodes
Number_of_nodeV2 = 0;
if (num_of_Nodes < 1)
{
cout << "error, please enter correct numbers" << endl;
}
else
{
start = new node(value); //this is pointing to node that has value in it.
//start == NULL;
node* tracker = start;
for (int i = 0; i < num_of_Nodes - 1; i++)
{
tracker->next_node = new node(value); //this track each node //-> de-renecen
tracker = tracker->next_node;
}
}
}
void link_list::Add(int store_node)
{
node* tracker = start;
node* newVal = new node(store_node);
while (tracker->next_node != NULL)
{
tracker = tracker->next_node;
}
tracker->next_node = newVal;
}
void link_list::Print()
{
node* tracker = start;
while (tracker != NULL)
{
cout << tracker->info << endl;
tracker = tracker->next_node;
cout << size;
}
}
void link_list::delete_at_middle(int delete_node)
{
//int center = 0;
node* tracker = start;
node* tracker2 = end;
node* temp;
node* temp1;
temp1 = temp = start;
if (start == NULL)
{
cout << "the list is empy" << endl;
}
else //this is where I cant seem to answer, thanks
{
while (temp != end)
{
temp = temp1->next_node;
if (temp->info = delete_node)
{
delete temp;
temp1->next_node = NULL; //ffffffffffff
}
}
tracker = tracker->next_node;
for (size_t i = 0; i < length; i++)
{
pre = start;
pre
}
//iltertae with tracker until the tracker has hit the center
}
}
int main() {
int Nodes_store = 0;
int delete_node = 0;
cout << "please enter the number of nodes" << endl;
cin >> Nodes_store;
cout << "please enter the number of to delete nodes" << endl;
cin >> delete_node;
link_list list = link_list(0, Nodes_store);
list.Print();
//list.delete_at_middle();
//list.Print();
//
//list.insert_at_middle(7);
//list.Print();
}AS'
;'

Program keeps breaking [closed]

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 6 years ago.
Improve this question
Write the definition of the function moveNthFront that takes as a parameter a positive integer, n. The function moves the nth element of the queue to the front. The order of the remaining elements remains unchanged. For example, suppose:
queue = {5, 11, 34, 67, 43, 55} and n = 3.
After a call to the function moveNthFront:
queue = {34, 5, 11, 67, 43, 55}.
Add this function to the class queueType. Also, write a program to test your method.
Here is my header
#ifndef queueType_H
#define queueType_H
#include<iostream>
class queueType
{
private:
class Queue
{
friend class queueType;
int value;
Queue *next;
Queue(int value1, Queue *next1 = NULL)
{
value = value1;
next = next1;
}
};
// These track the front and rear of the queue
Queue *front;
Queue *rear;
Queue *head;
public:
void moveNthFront(int);
Here is the cpp for the header.
#include"queueType.h"
#include<iostream>
using namespace std;
queueType::queueType() {
front = NULL;
rear = NULL;
}
queueType::~queueType() {
clear();
}
void queueType::enqueue(int num)
{
if (isEmpty())
{
front = new Queue(num);
rear = front;
}
else
{
rear->next = new Queue(num);
rear = rear->next;
}
}
void queueType::dequeue(int &num)
{
Queue *temp;
if (isEmpty())
{
cout << "The queue is empty.\n";
exit(1);
}
else
{
num = front->value;
temp = front;
front = front->next;
delete temp;
}
}
bool queueType::isEmpty() const
{
if (front == NULL)
return true;
else
return false;
}
int queueType::search(int x)
{
if (front == NULL)
return -1;
else
{
int count = 0;
Queue *aptr = front;
while (aptr != NULL)
{
if (aptr->value == x)
return count;
aptr = aptr->next;
count++;
}
return -1;
}
}
void queueType::clear()
{
int value; // Dummy variable for dequeue
while (!isEmpty())
dequeue(value);
}
void queueType::remove(int pos)
{
if (front == NULL)
return;
else if (pos == 0)
front = front->next;
else
{
int count = 0;
Queue *now = front, *past;
while (now != NULL && count != pos)
{
past = now;
now = now->next;
count++;
}
if (now)
{
past->next = now->next;
delete now;
}
}
}
void queueType::insert(int x, int pos )
{
Queue *now, *past;
if (front == NULL)
front = new Queue(x);
else if (now != NULL && pos == 0)
{
now = front;
;
for (int i = 0; i < 5; i++)
{
past = now;
now = now->next;
}
past->next = new Queue(x, now);
}
else
{
now = front;
int count = 0;
while (now != NULL && count != pos)
{
past = now;
now = now->next;
count++;
}
past->next = new Queue(x, now);
}
}
Here is my main
#include"queueType.h"
#include<iostream>
using namespace std;
int main() {
queueType intqueue;
int input, temp, x = 0;
for (int i = 0; i < 5; i++) {
intqueue.enqueue(i*i);
}
cout << "The values in the queue were:\n";
while (!intqueue.isEmpty())
{
int value;
intqueue.dequeue(value);
cout << value << " ";
}
for (int i = 0; i < 5; i++) {
intqueue.enqueue(i*i);
}
cout << "\nEnter the value to find:" << endl;
cin >> input;
intqueue.search(input);
temp = intqueue.search(input);
intqueue.remove(temp);
intqueue.insert(input, 0);
cout << "\nThe values after change was made:\n";
while (!intqueue.isEmpty())
{
int value;
intqueue.dequeue(value);
cout << value << " ";
}
return 0;
}
In insert method
else if (now != NULL && pos == 0)
{
this part can never run because now is null as it has never been initialized.
Then control goes to else part
where if pos =0 *past is never initialized.
Initialize *now first.
else you can remove else if part and just initialize *past once outside the while loop i.e.
else
{
now = front;
int count = 0;//here initialize past once past=now;
while (now != NULL && count != pos)
{
past = now;
now = now->next;
count++;
}
past->next = new Queue(x, now);
}
I edited it. It works for all positions except for 0 pos.
I need the element to go to the front of the queue.
void queueType::insert(int x, int pos )
{
Queue *now, *past;
if (front == NULL)
front = new Queue(x);
else
{
now = front;
int count = 0;
while (now != NULL && count != pos)
{
past = now;
now = now->next;
count++;
}
past->next = new Queue(x, now);
}
}