Implementation of the queue of the data structure (challenge programming 2)

Implementation of the queue of the data structure

The idea of ​​a queue is the most common when the CPU handles multitasking. Let's look at an example first.

topic

The existing n tasks named namei and processing time timei are arranged in a row, and the CPU processes these tasks one by one through the round-robin scheduling method, and each task processes at most q ms (this time becomes a time slice). If the task has not been processed after q ms, the task will be moved to the end of the queue, and the CPU will immediately start processing the next task.
Example: Assuming q is 100, then there is the following task queue
A(150)—B(80)—C(200)—D(200).
First, A is processed for 100ms, and then moves to the end of the queue with the remaining 50ms.
B(80)—C(200)—D(200)—A(50)
Next, B is processed for 80ms, and the processing is completed and disappears from the queue at 180ms.
C(200)—D(200)—A(50)
and so on
———————————————————————————————————— —

enter

nq
name1 time1
name2 time2
... ...
In the first line, enter the integer n representing the number of tasks and the integer q representing the time slice, separated by a space.
The next n lines enter the information for each task. The string name and timei are separated by a space.

output

Output each task name and end time according to the order in which the tasks are completed. The task name and the corresponding end time are separated by a space. Each pair of task name and end time occupies 1 line.

limit

1 ≤ n ≤ 100 000
1 ≤ q ≤ 1000
1 ≤ timei ≤ 50 000
1 ≤ length of string namei ≤ 10
1 ≤ sum of timei ≤ 1 000 000

input example

5 100
p1 150
p2 80
p3 200
p4 350
p5 20

output example

p2 180
p5 400
p1 450
p3 550
p4 800

Look at the code first

#include<stdio.h>
#include<string.h>
#define LEN 10005

typedef struct PP {
    
    
	char name[100];
	int t;
} P;

P Q[LEN];

int head, tail, n;          //n代表总任务数

bool isEmpty() {
    
    
	return head == tail;
}

void enqueue(P x) {
    
              //该函数用来向队列尾添加元素
	Q[tail] = x;
	tail = (tail + 1) % LEN;
}

P dequeue() {
    
                   //该函数用来从队列前取出元素
	P x = Q[head];
	head = (head + 1) % LEN;
	return x;
}

int min(int a, int b) {
    
     return a < b ? a : b; }

int main()
{
    
    
	int elaps = 0, c;
	int i, q;                    //q代表的是时间片
	P u;
	scanf("%d %d", &n, &q);
	//按顺序添加任务到队列
	for (i = 1; i <= n ; i++)
	{
    
    
		scanf("%s", Q[i].name);
		scanf("%d", &Q[i].t);
	}
	head = 1; tail = n + 1;

	while (tail != head)
	{
    
    
		u = dequeue();
		c = min(q, u.t);
		u.t -= c;
		elaps += c;
		if (u.t > 0)
		{
    
    
			enqueue(u);
		}
		else
		{
    
    
			printf("%s %d\n", u.name, elaps);
		}
	}
	return 0;
}

The queue can be simulated by using an array, which mainly requires the following variables and functions
1. An array to store data: Q
2. The head used as a head pointer, dequeue will take out the element pointed to by the head every time.
3. The tail pointing to the end of the queue, its value is n+1, each enqueue will store the processed data behind the end of the data.
4. enqueue (x) function, add elements to the queue, note that he is a parameter
5. dequeue () function, a function used to take out elements.
When the program is running, the element will be taken out from the beginning of Q and added to the position indicated by tail with enqueue after processing. This process continues until the head and tail are equal, and the process is completed.

However, to do this, you first need to ensure that the length of the array is sufficient, otherwise when tail+1 is easy to cause the array subscript to go out of bounds. When dealing with large data, the length of the array may be terrifying.
If you want to avoid this situation, you need to keep the head pointer at 0, and move all the data to the beginning of the array after each execution of dequeue(). The downside is that each move adds O(n) complexity.
The solution in the book is to use a ring buffer to manage the data.
Alt
It can be understood as a second hand. When tail+1=12 exceeds the range of the array, it is set to 0. Similar to 1 minute has passed, and the calculation starts from 1 second.

//对head和tail的操作
head = (head + 1) % MAX      //MAX表示数组元素个数
tail = (tail + 1) % MAX      

These two expressions will set head and tail to 0 when they exceed the number of array data.

The ring buffer can implement dequeue and enqueue operations at the same time with a complexity of O(1).

Queue and stack are two simple data structures worth studying carefully.

Guess you like

Origin blog.csdn.net/qq_32577169/article/details/94970351