datawhale algorithm and data structure day4-queue

datawhale algorithm and data structure (above) 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 head;
	int tail;
};
 
#endif

#Definition of Sequential Queue Class
#include <iostream>
#include "sq.h"
using namespace std;
 
sq::sq()
{
	head = -1;   
	tail = -1;
}
 
void sq::push(dataType var)
{
	queue[++tail] = var;
 
	if(tail == 0) 
	{
		head = 0;
	}
}
 
void sq::pop()
{
	++head;
}
 
dataType sq::front()
{
	return queue[head];
}
 
bool sq::isEmpty()
{
	bool flag = head > tail;     //When head and tail are not -1
 
	if(head == -1 && tail == -1) //When head=tail=-1
	{
		flag = true;
	}
 
	if(flag)
	{
		head = tail = -1;
	}
 
	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
    //c.business_time=10+rand()%31; 
}
//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.business_time=10+rand()%31;  
    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;
    customer.end_time.h=customer.start_time.h+(customer.start_time.m+customer.business_time)/60;
    customer.end_time.m=(customer.start_time.m+customer.business_time)%60;
    //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+
        cus_queue[i].front().business_time <= (customer.arrive_time.h)*60+customer.arrive_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].business_time=10+rand()%31;   
             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;
             customer[i].end_time.h=customer[i].start_time.h+(customer[i].start_time.m+customer[i].business_time)/60;
             customer[i].end_time.m=(customer[i].start_time.m+customer[i].business_time)%60;
             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<<" bussiness_time: "<<customer[i].business_time<<"min\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
Private letter follow

Tags: Windows Programming

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