# datawhale algorithm and data structure day4-queue

## Theoretical part

### 1. Queues

1. Definition
Instead of a stack, a queue is a linear first-in-first-out (FIFO).Insertions are allowed only at one end of the table and deletions of elements at the other end.In a queue, the end that allows insertion is called the end of the queue, and the section that allows deletion is called the head of the queue.

Queues often appear in programming.One of the most typical examples is job queuing in the operating system.In a computer system that allows multiple programs to run, several jobs are running at the same time.If the results of the run need to be output through the channel, queue them in the order in which they are requested to be output.

2. Implement a sequential queue with an array

```#Description sq.h

#ifndef _SQ_H_
#define _SQ_H_

typedef int dataType;
#define maxSize 100

class sq
{
public:
sq();
//~sq();
void push(dataType var);
void pop();
dataType front();
bool isEmpty();
bool isFull();

private:
dataType queue[maxSize];
int tail;
};

#endif

#Definition of Sequential Queue Class
#include <iostream>
#include "sq.h"
using namespace std;

sq::sq()
{
tail = -1;
}

void sq::push(dataType var)
{
queue[++tail] = var;

if(tail == 0)
{
}
}

void sq::pop()
{
}

dataType sq::front()
{
}

bool sq::isEmpty()
{
bool flag = head > tail;     //When head and tail are not -1

{
flag = true;
}

if(flag)
{
}

return flag;
}

bool sq::isFull()
{
return tail == maxSize-1;
}

#main.cpp

#include <iostream>
#include "sq.h"
using namespace std;

int main()
{
sq exp;
int i = 0;

for(i=0;i<maxSize+10;++i)
{
if(!exp.isFull())
{
exp.push(i);
}
}

for(i=0;i<maxSize+20;++i)
{
if(!exp.isEmpty())
{
cout<<exp.front()<<endl;
exp.pop();
}
}

if(exp.isEmpty())
{
cout<<"Queue empty!"<<endl;
}

return 0;
}

```
1. Array implements a circular queue
```#include
using namespace std;
template
class queue
{
private:
int front;//End-to-end subscript
int rear;
int Maxsize;
T *q;
public:
queue(int Msize) :Maxsize(Msize)//The effect is to initialize the MAXSZE variable
{
q = new T[Maxsize];//q points to the first address of the allocated array, which is the array name
front = rear = 0;
}
~queue(){ delete q; }
int size(){ return (rear - front + Maxsize) % Maxsize; }

bool enqueue(const T& v)
{
if (size() == Maxsize)
{
cout << "The queue is full" << endl;
return false;
}
else
{
q[rear] = v;//There's something awkward about pointers being used as subscripts to arrays
rear = (rear + 1) % Maxsize;
return true;
}
}

int  dequeue(T v)
{
if (size() == 0)
{
cout << "queue is empty" << endl;
return 0;
}
else
{
v=q[front];
q[front] = NULL;
front = (front + 1) % Maxsize;//Since it's an array, you don't need to release it, just make it Null
return v;
}
}
};

int main()
{
char m;
queue  q1(20);
cout << "input a Enter the team, b Out of the team, c Sign out!" << endl;
cin >> m;
while (m != 'c')
{
if (m == 'a')
{
int i,j;
cout << "Enter a number below 20, the number of teams you need to join:";
cin >> i;
for (j = 0; j < i; j++)
{
int k;
cin >> k;
q1.enqueue(k);
cout << "This is the number of elements in the current queue:" << q1.size() << endl;
}
cout << "The queue is full, please enter b Make a queue operation or input c Sign out!" << endl;
cin >> m;//To keep the operation continuous
}
if (m == 'b')
{
while (q1.size() != 0)
{
int n;
cout << "Enter the number to which you want the queue element to be assigned (Note: Queue must exist)" << endl;
cin >> n;
cout <<" The number assigned to the input by the outgoing element, that is n=" << q1.dequeue(n) << endl;
cout << "This is the number of elements in the current queue" << q1.size() << endl;
}
cout << "Please enter first a:Queue some elements,Or input c Exit the operation!" << endl;
cin >> m;//To keep the operation continuous
}
}
}
```
1. Array implements a chain queue
```#include
using namespace std;
template
class queue
{
private:
int front;//End-to-end subscript
int rear;
int Maxsize;
T *q;
public:
queue(int Msize) :Maxsize(Msize)//The effect is to initialize the MAXSZE variable
{
q = new T[Maxsize];//q points to the first address of the allocated array, which is the array name
front = rear = 0;
}
~queue(){ delete q; }
int size(){ return (rear - front + Maxsize) % Maxsize; }

bool enqueue(const T& v)
{
if (size() == Maxsize)
{
cout << "The queue is full" << endl;
return false;
}
else
{
q[rear] = v;//There's something awkward about pointers being used as subscripts to arrays
rear = (rear + 1) % Maxsize;
return true;
}
}

int  dequeue(T v)
{
if (size() == 0)
{
cout << "queue is empty" << endl;
return 0;
}
else
{
v=q[front];
q[front] = NULL;
front = (front + 1) % Maxsize;//Since it's an array, you don't need to release it, just make it Null
return v;
}
}
};

int main()
{
char m;
queue  q1(20);
cout << "input a Enter the team, b Out of the team, c Sign out!" << endl;
cin >> m;
while (m != 'c')
{
if (m == 'a')
{
int i,j;
cout << "Enter a number below 20, the number of teams you need to join:";
cin >> i;
for (j = 0; j < i; j++)
{
int k;
cin >> k;
q1.enqueue(k);
cout << "This is the number of elements in the current queue:" << q1.size() << endl;
}
cout << "The queue is full, please enter b Make a queue operation or input c Sign out!" << endl;
cin >> m;//To keep the operation continuous
}
if (m == 'b')
{
while (q1.size() != 0)
{
int n;
cout << "Enter the number to which you want the queue element to be assigned (Note: Queue must exist)" << endl;
cin >> n;
cout <<" The number assigned to the input by the outgoing element, that is n=" << q1.dequeue(n) << endl;
cout << "This is the number of elements in the current queue" << q1.size() << endl;
}
cout << "Please enter first a:Queue some elements,Or input c Exit the operation!" << endl;
cin >> m;//To keep the operation continuous
}
}
}

```

## Exercises

Simulate bank service completion procedure code.

At present, queuing (call) system is widely used in window industry represented by bank business hall. This system completely simulates the whole process of queuing. It replaces the hard work of people's standing queue by functions such as ticket-taking, queuing and waiting, call service, etc.

The specific operation flow of queued call software is:

• Customer takes service number
When the customer arrives at the service lobby, go to the dialer placed next to the entrance and press the corresponding service button on it. The Dialer will print out a service list automatically.The service number and the number of people waiting for service in front of it are shown on the list.

• Service Employee Calls Customer
The service employee only needs to press the corresponding button of the caller on his counter, and the customer's service number will be displayed on the display in sequence, and "ding" and related voice information will be sent out to prompt the customer to go to the window.When a customer is done, the desk service employee can automatically call the next customer by simply pressing the appropriate key on the caller.

Write a program to simulate the above work, the main requirements are as follows:

• After the program runs, when you see the prompt "Please click on the touch screen to get the number:", just press the Enter key to display the prompt "Your number is: XXX, you have YYY digit in front of you". XXX is the service number you got, YYY is the number of people who arrived before XXX waiting for service.
• Use multi-threaded technology to simulate service windows (which can simulate multiple), with the behavior of attendants calling customers. Assume that each customer is served for 10,000 Ms. When the time is up, display "Please XXX to ZZZ window!"Tips.Among them, ZZZ is the window number that will be serving customers.
```#include<iostream>
#include <stdlib.h>
#include <time.h>
#include<windows.h>
using namespace std;
int K,N;   //Define the number of bank service windows and the number of customers in a day

//Define Chain List Nodes
template<class T>
struct chainNode
{
//Data Members
T element;
chainNode<T> *next;
//Method
chainNode(){}
chainNode(const T& element){
this->element=element;
}
chainNode(const T& element,chainNode<T> *next){
this->element=element;
this->next=next;
}
};

//Define Queue
template<class T>
class queue{
public:
queue();       //Initialize Queue
~queue(){};    //Destructor
bool empty(){  //Determine if the queue is empty
return queueSize==0;
}
int size(){    //Returns the number of elements in the queue
return queueSize;
}
T& front(){    //Return the first element of the queue
return queueFront->element;
}
T& back(){     //Return Queue End Element
return queueBack->element;
}
chainNode<T> * begin(){
return queueFront;
}
void pop();    //Delete first element
void push(const T& theElement);
private:
int queueSize;        //queue length
chainNode<T> *queueFront;  //Pointer to the first element of the queue
chainNode<T> *queueBack;   //Pointer to last element of queue
};
template<class T>
queue<T>::queue(){
queueFront=queueBack=NULL;
queueSize=0;
}

template<class T>
void queue<T>::pop(){
if(queueFront==NULL) {
cout<<"you queue is empty!";
return;
}
chainNode<T> *nextNode=queueFront->next;
delete queueFront;
queueFront=nextNode;
queueSize--;
}

template<class T>
void queue<T>::push(const T& theElement){
//Request a new element node
chainNode<T> *newNode=new chainNode<T>(theElement,NULL);
//Insert a new node at the end of the queue
if(queueSize==0)  queueFront=newNode; //Queue empty
else  queueBack->next=newNode;        //The team is not empty
queueBack=newNode;
queueSize++;
}

//Define time
struct thetime{
int h;  //time
int m;  //branch
};
//Define the arrival time, wait time, start processing time, business processing time, end business time (departure time) for each customer
struct customers{
struct thetime arrive_time;     //Arrival bank time
struct thetime wait_time;       //waiting time
struct thetime start_time;      //Start business hours
int business_time;              //Business processing time (assuming that the business processing time is an integer and the processing time range is 10-40 minutes)
struct thetime end_time;        //Close business hours
int in_bank_number;             //Sequence number of customer entry into bank
};
//Show window service
void show_queue(queue<customers> cus_queue[]){
Sleep(1000);
for(int i = 0;i < K;i++) {
cout<<"window"<<i+1<<": ";
chainNode<customers> *m = cus_queue[i].begin();
while(m != NULL) {
cout<<"Customer"<<m->element.in_bank_number<<" ";
m = m -> next;
}
cout<<endl;
}
cout<<endl;
}

//User Arrival Bank Timesheet Function
void customers_time(struct customers &c){
//Random customer arrival at bank
c.arrive_time.h=9+rand()%8;
c.arrive_time.m=rand()%60;
//Random Generation of Customer Business Processing Time
}
//Sort users in order of their arrival time (since the user's arrival time is random)
void customer_sort(customers customer[]){
int max_time_index;   //Record subscripts corresponding to the latest time of arrival of the customer
customers max_time_cus,swap_cus;
//Sort by selection sort
for(int i=N-1;i>0;i--)
{
max_time_cus=customer[i];
max_time_index=i;
//Find the Latest Arrival Time
for(int j=0;j<i;j++)
{
if((customer[j].arrive_time.h)*60+customer[j].arrive_time.m > (max_time_cus.arrive_time.h)*60+max_time_cus.arrive_time.m)
{
max_time_cus=customer[j];
max_time_index=j;
}
}
if(i!=max_time_index){
//swap section
swap_cus=customer[i];
customer[i]=max_time_cus;
customer[max_time_index]=swap_cus;
}
}

}

//Determine which window the customer needs to queue to, that is, figure out the queue with the least waiting time
int judge_queue_in(queue<customers> cus_queue[],customers &customer,int each_queue_cus_number[]) {
//Put the time users need to wait in each queue in an array
int each_queue_wait_time[K];
for(int i=0;i<K;i++) {
//The client's waiting time depends on the last person on his team's closing time
int wait_h=cus_queue[i].back().end_time.h-customer.arrive_time.h;
each_queue_wait_time[i]=wait_h*60+cus_queue[i].back().end_time.m-customer.arrive_time.m;
}
//Find the queue that takes the least time
int min_time_queue_index=0;
for(int j=1;j<K;j++) {
if(each_queue_wait_time[j] < each_queue_wait_time[min_time_queue_index])
min_time_queue_index=j;
}
//Define customer data
customer.wait_time.h=each_queue_wait_time[min_time_queue_index]/60;
customer.wait_time.m=each_queue_wait_time[min_time_queue_index]%60;
customer.start_time.h=cus_queue[min_time_queue_index].back().end_time.h;
customer.start_time.m=cus_queue[min_time_queue_index].back().end_time.m;
//Queue customers
//It's time to close the bank. Customers who are still in the process are allowed to continue their business before leaving. Customers who are still in the queue are allowed to leave immediately.
if((customer.start_time.h)*60+customer.start_time.m < 17*60) {
cus_queue[min_time_queue_index].push(customer);
each_queue_cus_number[min_time_queue_index]++;
}
return min_time_queue_index;
}

//Determine which queue's first customer has completed business and left the queue when the next customer arrives
void leave_queue(queue<customers> cus_queue[],customers customer){
for(int i=0;i<K;i++) {
while(!cus_queue[i].empty() && (cus_queue[i].front().start_time.h)*60+cus_queue[i].front().start_time.m+
cout<<"----------Customer"<<cus_queue[i].front().in_bank_number<<"Leave the window"<<i+1<<"----------"<<endl;
cus_queue[i].pop();
}
}
//show_queue(cus_queue);
}

//User Entry Queue Function
void customers_in_queue(queue<customers> cus_queue[],customers customer[],int each_queue_cus_number[]) {
//Determine which window is free
int queue_number;
for(int i=0;i<N;i++) {
bool queue_free=false;
//Each time you enter the queue, determine if the head of each queue has completed business
leave_queue(cus_queue,customer[i]);
for(int j=0;j<K;j++) {
//Idle in window
if(cus_queue[j].empty())
{
//Every time a customer enters a queue, he or she needs to determine if each of the first customers has completed the business.
customer[i].wait_time.h=0;
customer[i].wait_time.m=0;
customer[i].start_time.h=customer[i].arrive_time.h;
customer[i].start_time.m=customer[i].arrive_time.m;
cus_queue[j].push(customer[i]);
each_queue_cus_number[j]++;
queue_free=true;
cout<<"----------Customer"<<customer[i].in_bank_number<<"Arrived at the window"<<j+1<<"----------"<<endl;
cout<<"Customer"<<customer[i].in_bank_number<<"Number of people to wait: 0"<<endl;
break;
}
}
//No idle in the window
if(queue_free==false){
queue_number = judge_queue_in(cus_queue,customer[i],each_queue_cus_number);   //Determine which queue has the least waiting time
cout<<"----------Customer"<<customer[i].in_bank_number<<"Arrived at the window"<<queue_number<<"----------"<<endl;
cout<<"Customer"<<customer[i].in_bank_number<<"Number of people to wait:"<<cus_queue[queue_number].size()-1<<endl;
}
show_queue(cus_queue);
}
//Show the exit status of the last customer
leave_queue(cus_queue,customer[N]);
show_queue(cus_queue);
}

int main(){
//srand(time(0));
srand((unsigned int)time(NULL));  //Make the random number different after each compilation
welcom();   //Welcome Interface
cout<<"Please enter the number of bank service windows:";
cin>>K;
cout<<"Please enter the number of customers a day at the bank:";
cin>>N;
customers customer[N];
queue<customers> cus_queue[K];
int each_queue_cus_number[N];
for(int i=0;i<N;i++){
customers_time(customer[i]);       //Initial user time
each_queue_cus_number[i]=0;        //Number of Initial Window Service Customers
cout<<i+1<<" arrive_time: "<<customer[i].arrive_time.h<<": ";
cout<<customer[i].arrive_time.m<<endl;
}
customer_sort(customer);  //Sort customers in the order they enter the bank
cout<<"---------------------------after sort---------------------------"<<endl;
for(int i=0;i<N;i++){
//Sleep(2000);
customer[i].in_bank_number = i + 1;
cout<<i+1<<" arrive_time: "<<customer[i].arrive_time.h<<": ";
cout<<customer[i].arrive_time.m<<endl;
}
cout<<"---------------------------begin serve---------------------------"<<endl;
customers_in_queue(cus_queue,customer,each_queue_cus_number);  //Customer Queue
cout<<"---------------------------end serve---------------------------"<<endl;
cout<<"---------------------------after customer in queue---------------------------"<<endl;
for(int i=0;i<N;i++){
cout<<i+1<<" start_time: "<<customer[i].start_time.h<<":"<<customer[i].start_time.m<<"\t";
cout<<i+1<<" end_time: "<<customer[i].end_time.h<<":"<<customer[i].end_time.m<<"\t";
cout<<i+1<<"  wait_time: "<<(customer[i].wait_time.h)*60+customer[i].wait_time.m<<" "<<endl;
}
int max_cus_wait_time=(customer[0].wait_time.h)*60+customer[0].wait_time.m;
int sum_cus_wait_time=max_cus_wait_time;
for(int i=1;i<N;i++){
if((customer[i].wait_time.h)*60+customer[i].wait_time.m > max_cus_wait_time)
max_cus_wait_time=(customer[i].wait_time.h)*60+customer[i].wait_time.m;
sum_cus_wait_time+=(customer[i].wait_time.h)*60+customer[i].wait_time.m;
}
int actual_cus_numbers=0;
for(int i=0;i<K;i++){
cout<<"window"<<i+1<<"Number of Service Customers: "<<each_queue_cus_number[i]<<endl;
actual_cus_numbers+=each_queue_cus_number[i];
}
cout<<"max_cus_wait_time: "<<max_cus_wait_time<<"min"<<endl;
cout<<"avg_cus_wait_time: "<<(double)sum_cus_wait_time/actual_cus_numbers<<"min"<<endl;
return 0;
}
```

[Source]
[1] Data structure
[2] https://blog.csdn.net/Lulipeng_cpp/article/details/10754495
[3] https://blog.csdn.net/jx232515/article/details/51483957
[4] https://blog.csdn.net/jx232515/article/details/51483957
[5] https://blog.csdn.net/Hachi_Lin/article/details/79774526

Six original articles were published. Approved 0. Visits 73

Tags: Windows Programming

Posted on Mon, 13 Jan 2020 19:29:03 -0500 by eagleweb