• 队列


    队列按照先进先出(First In First Out, FIFO)的规则管理数据。

    操作

    • enqueue(x):在队列末尾添加元素x
    • dequeue():从队列开头取出元素

    规则
    数据中最先进入的队列的元素最先被取出。


    以上都是队列的逻辑结构,队列的实现可以使用数组和链表。下面的例子将用数组来实现一个队列并进行操作。

    以AOJ(Aizu Online Judge)中的一题多任务处理为例进行说明。题目链接 http://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=ALDS1_3_B

    There are (n) processes in a queue. Each process has (name_i) and (time_i). The round-robin scheduling handles the processes in order. A round-robin scheduler gives each process a quantum (a time slot) and interrupts the process if it is not completed by then. The process is resumed and moved to the end of the queue, then the scheduler handles the next process in the queue.

    For example, we have the following queue with the quantum of 100ms.

    A(150) - B(80) - C(200) - D(200)
    

    First, process A is handled for 100ms, then the process is moved to the end of the queue with the remaining time (50ms).

    B(80) - C(200) - D(200) - A(50)
    

    Next, process B is handled for 80ms. The process is completed with the time stamp of 180ms and removed from the queue.

    C(200) - D(200) - A(50)
    

    Your task is to write a program which simulates the round-robin scheduling.

    Input

    (n) (q)
    (name_1) (time_1)
    (name_2) (time_2)
    ...
    (name_n) (time_n)
    In the first line the number of processes (n) and the quantum q are given separated by a single space.

    In the following (n) lines, names and times for the (n) processes are given. (name_i) and (time_i) are separated by a single space.

    Output

    For each process, prints its name and the time the process finished in order.

    Constraints
    1 ≤ n ≤ 100000
    1 ≤ q ≤ 1000
    1 ≤ (time_i) ≤ 50000
    1 ≤ length of (name_i) ≤ 10
    1 ≤ Sum of (time_i) ≤ 1000000

    Sample Input 1
    5 100
    p1 150
    p2 80
    p3 200
    p4 350
    p5 20
    Sample Output 1
    p2 180
    p5 400
    p1 450
    p3 550
    p4 800

    题目大意是给出(n)个任务,名称和时间分别为(name_i)(time_i),这个任务排成一列,CPU按照循环调度法逐一处理这些任务,每次处理的时间为(q),没有处理完的任务排到队列的末尾,如此循环,直到所有任务处理完成。

    我们这个时候就使用队列模拟循环调度法。没有使用Java中的集合类,而是使用数组来定义一个队列。主要需要定义的操作是出队和入队,需要定义的变量为队头指针和队尾指针。要注意的一点是定义队头和队尾指针时是指向的什么地方,比如队头指针指向开头的第一个元素,队尾指针指向最后一个元素,也可以定义为指向最后一个元素的后一个元素,这个可能会影响出队和入队的操作。定义之后按照自己定义的位置写相应的代码即可。

    如果使用普通的数组操作,在一段时间之后队头队尾指针都会指向数组的末尾,这时就不能添加元素,空间也被浪费了。所以我们使用循环数组,本质也还是一个普通数组,只是在超出数组范围之后再从头开始,借助于取余操作来实现。使用循环数组后又出现了一个问题,我们无法区分队列的空与满,所以我们规定队列至少留一个空位(在判断队空和队满的情况下能体现出来)。

    参考代码如下:

    import java.util.Scanner;
    
    class Task{
        String name;
        int time;
    }
    
    public class Main {
    
        static final int len = 100005;
        static Task[] num = new Task[len];
    
        static int head = 0;
        static int tail = 0;
    
        // 没有考虑队列满的情况
        public static void enqueue(Task task){
            num[tail] = task;
            tail = (tail+1) % len;
        }
    
        // 没有考虑队列空的情况
        public static Task dequeue(){
            Task temp = num[head];
            head = (head+1) % len;
            return temp;
        }
    
        public static void main(String[] args) {
    
            Scanner sc = new Scanner(System.in);
            int n = sc.nextInt();
            int q = sc.nextInt();
            for (int i=0; i<n; i++){
    			// 此处不能直接使用num[i].name,因为数组内放的是对象,对象的默认值为null,会抛出空指针异常。必须先创建对象
                Task temp = new Task();
                temp.name = sc.next();
                temp.time = sc.nextInt();
                enqueue(temp);
            }
    
            tail = n;
    
            int sum = 0;
    
            //当队列不为空时,我们进行下列操作
            while (head != tail){
                Task temp = dequeue();
                if (temp.time <= q){
                    sum += temp.time;
                    System.out.println(temp.name + " " + sum);
                }
                else {
                    temp.time -= q;
                    enqueue(temp);
                    sum += q;
                }
            }
        }
    
    }
    
  • 相关阅读:
    python 线程队列、线程池、全局解释器锁GIL
    java Cookie 获取历史记录列表(三)
    Java中如何读写cookie (二)
    java读取和写入浏览器Cookies
    zookeeper的安装和部署
    Spring Boot 多模块项目创建与配置 (一)
    十款效果惊艳的Html案例(一)
    phython
    阿里高并发所用到的技术
    Java9新特性
  • 原文地址:https://www.cnblogs.com/WanJiaJia/p/7976117.html
Copyright © 2020-2023  润新知