📜  单个资源预留的数据结构

📅  最后修改于: 2021-05-24 21:21:59             🧑  作者: Mango

设计一种数据结构,以便在以下约束条件下在一台计算机上保留将来的作业。
1)每个作业都需要机器的k个时间单位。
2)机器一次只能执行一项工作。
3)时间是系统的一部分。未来的工作会在不同的时间出现。仅当在k个时间段内(之后和之前)没有任何保留的情况下,才保留对未来作业的保留
4)每当作业完成时(或其保留时间加k等于当前时间),就会将其从系统中删除。

例子:

Let time taken by a job (or k) be = 4

At time 0: Reservation request for a job at time 2 in 
           future comes in, reservation is done as machine 
           will be available (no conflicting reservations)
Reservations {2}

At time 3: Reservation requests at times 15, 7, 20 and 3.
           Job at 7, 15 and 20 can be reserved, but at 3 
           cannot be reserved as it conflicts with a 
           reserved at 2.
Reservations {2, 7, 15, 20}

At time 6: Reservation requests at times 30, 17, 35 and 45
           Jobs at 30, 35 and 45 are reserved, but at 17  
           cannot be reserved as it conflicts with a reserved 
           at 15.
Reservations {7, 15, 30, 35, 45}.
Note that job at 2 is removed as it must be finished by 6.

让我们考虑此任务的不同数据结构。

一种解决方案是使所有将来的保留按数组排序。可以使用二进制搜索在O(Logn)中完成检查冲突的时间复杂度,但是插入和删除操作需要O(n)时间。

此处不能使用散列,因为搜索不是精确搜索,而是在k个时间范围内的搜索。

这个想法是使用二进制搜索树来维护一组保留的作业。对于每个预订请求,仅在没有冲突的预订时才插入。插入作业时,请执行“在k个时间范围内检查”。如果从根插入路径上有ak远的节点,则拒绝保留请求,否则进行保留。

// A BST node to store future reservations
struct node
{
    int time; // reservation time
    struct node *left, *right;
};
  
// A utility function to create a new BST node
struct node *newNode(int item)
{
    struct node *temp =
        (struct node *)malloc(sizeof(struct node));
    temp->time = item;
    temp->left = temp->right = NULL;
    return temp;
}
  
/* BST insert to process a new reservation request at
   a given time (future time).  This function does
   reservation only if there is no existing job within
   k time frame of new job  */
struct node* insert(struct node* root, int time, int k)
{
    /* If the tree is empty, return a new node */
    if (root == NULL) return newNode(time);
  
    // Check if this job conflicts with existing
    // reservations
    if ((time-k < root->time) && (time+k > root->time))
        return root;
  
    /* Otherwise, recur down the tree */
    if (time < root->time)
        root->left  = insert(root->left, time, k);
    else
        root->right = insert(root->right, time, k);
  
    /* return the (unchanged) node pointer */
    return root;
}

删除作业是简单的BST删除操作。

正常的BST花费O(h)时间进行插入和删除操作。我们可以使用自平衡二进制搜索树(例如AVL,Red-Black,..)在O(Log n)时间内进行这两种操作。

这个问题是从麻省理工学院的讲座中采纳的。