【数据结构与算法实习】题目11 任务调度(Schedule)

题目描述:
某高性能计算集群(HPC cluster)采用的任务调度器与众不同。为简化起见,假定该集群不支持多任务同时执行,故同一时刻只有单个任务处于执行状态。初始状态下,每个任务都由称作优先级数的一个整数指定优先级,该数值越小优先级越高;若优先级数相等,则任务名ASCII字典顺序低者优先。此后,CPU等资源总是被优先级数最小的任务占用;每一任务计算完毕,再选取优先级数最小的下一任务。不过,这里的任务在计算结束后通常并不立即退出,而是将优先级数加倍(加倍计算所需的时间可以忽略)并继续参与调度;只有在优先级数不小于2^32时,才真正退出。
你的任务是,根据初始优先级设置,按照上述调度原则,预测一批计算任务的执行序列。

输入格式:
第一行为以空格分隔的两个整数n和m,n为初始时的任务总数,m为所预测的任务执行序列长度,每行末尾有一个换行符。
以下n行分别包含一个整数和一个由不超过8个小写字母和数字组成的字符串。前者为任务的初始优先级数,后者为任务名。数字和字符串之间以空格分隔。

要求:
0 ≤ n ≤ 4,000,000
0 ≤ m ≤ 2,000,000
0 < 每个任务的初始优先级 < 2^32
不会有重名的任务

输出格式:
最多m行,各含一个字符串。按执行次序分别给出执行序列中前m个任务的名称,若执行序列少于m,那么输出调度器的任务处理完毕前的所有任务即可。

输入样例:

3 3
1 hello
2 world
10 test

输出样例:

hello
hello
world

题解:

//本题的逻辑结构:树,最小堆
//本题的存储结构:顺序
//解题思路和算法:建立最小堆,按照输入的数据插入最小堆,进行最小堆排序,每次从最小堆中取出最小的数,判断
    // 是否存在优先级相同但ascll码相对较小的数据,如果存在则交换两个数据的信息, 并把ascll码相对较大的
    // 数据按原样存入最小堆,对应数据取出后输出字符串,之后将权值加倍并存入最小堆,进行排序,重复执行直到达到规定输出次数
//效率:时间复杂度O(n)、空间复杂度O(1):
//测试数据: (1)输入:
// 4 4
// 4 okok
// 5 vgvg
// 88 gljf
// 12 nihao
//输出; 
// okok
// vgvg
// okok
// vgvg
// (2)输入:
// 3 3
// 1 hello
// 2 world
// 10 test
// 输出:
// hello
// hello
// world


#include<stdio.h>
#include<malloc.h>
#include<stdlib.h>
#define MinDATA 1000
#define true 1
#define false 0
#define ERROR -1
typedef int bool;
typedef int ElementType;

ElementType MinDataRes;

typedef struct HNode * Heap;
struct HNode{
    ElementType * Order;
    ElementType * Data;
    int Size;
    int Capacity;
};
typedef Heap MinHeap;


MinHeap CreateHeap(int MinSize){
    MinHeap H = (MinHeap)malloc(sizeof(struct HNode));
    H->Order = (ElementType *)malloc((MinSize+1)*sizeof(ElementType));
    H->Data = (ElementType *)malloc((MinSize+1)*sizeof(ElementType));
    H->Size = 0;
    H->Capacity = MinSize;
    H->Order[0] = MinDATA;
    H->Data[0] = MinDATA;

    return H;
}

bool IsFull(MinHeap H){
    return (H->Size == H->Capacity);
}

bool Insert(MinHeap H, ElementType data, ElementType order){
    int i;
    if(IsFull(H)){
        printf("Is Full!\n");
        return false;
    }
    i =++H->Size;
    for(; H->Order[i/2]< data ; i/=2){
        H->Order[i] = H->Order[i/2];
        H->Data[i] = H->Data[i/2];
    }
    H->Order[i] = order;
    H->Data[i] = data;

    return true;
}

bool IsEmpty(MinHeap H){
    return (H->Size == 0);
}

ElementType DeleteMin(MinHeap H){
    int Parent, Child;
    ElementType MinOrder, data, order;
    if(IsEmpty(H)){
        printf("Is Empty!");
        return ERROR;
    }
    MinOrder = H->Order[1];
    MinDataRes = H->Data[1];
    data = H->Data[H->Size];
    order = H->Order[H->Size--];
    for(Parent = 1; Parent * 2<=H->Size; Parent = Child){
        Child = Parent *2;
        if((Child!=H->Size)&&(H->Order[Child]>H->Order[Child+1]))
            Child++;
        if(order<H->Order[Child])break;
        else
            H->Order[Parent] = H->Order[Child];
            H->Data[Parent] = H->Data[Child];
    }
    H->Order[Parent] = order;
    H->Data[Parent] = data;
    return MinOrder;
}

void PercDown(MinHeap H, int p){
    int Parent, Child;
    ElementType data, order;

    order = H->Order[p];
    data = H->Data[p];
    for(Parent = p; (Parent*2)<=H->Size; Parent = Child){
        Child = Parent * 2;
        if((Child != H->Size)&&(H->Order[Child]>H->Order[Child+1]))
            Child++;
        if(order <= H->Order[Child])break;
        else
            H->Order[Parent] = H->Order[Child];
            H->Data[Parent] = H->Data[Child];
    }
    H->Data[Parent] = data;
    H->Order[Parent] = order;

}

void HeapSort(MinHeap H){
    int i;

    for(i = H->Size/2; i>0; i--){
        PercDown(H, i);
    }
}


// void PercDown(ElementType A[], int p, int N){
//     int Parent, Child;
//     ElementType data;

//     data = A[p];
//     for(Parent = p; (Parent*2+1)<N; Parent = Child){
//         Child = Parent * 2 +1;
//         if((Child != N-1)&&(A[Child]<A[Child+1]))
//             Child++;
//         if(data >= A[Child])break;
//         else
//             A[Parent] = A[Child];
//     }
//     A[Parent] = data;
// }

// void Swap(ElementType *a, ElementType *b){
//     ElementType t=*a;
//     *a = *b;
//     *b = t;
// }

// void HeapSort(ElementType A[], int N){
//     int i;
//     for(i = N/2-1; i>=0; i--){
//         PercDown(A, i, N);
//     }
//     for(i = N-1; i>0; i--){
//         Swap(&A[0], &A[i]);
//         PercDown(A, 0, i);
//     }
// }

struct Result{
    int * Data2;
    char *content2[1000];
};

int main(){
    

    MinHeap H = CreateHeap(1000);
    int n, m;

    scanf("%d %d", &n, &m);
    char *NR[1000];
    for(int i = 0; i<n;i++){
        int pre;
        NR[i] = (char *)malloc(sizeof(char *));
        scanf("%d %s", &pre, NR[i]);
        Insert(H, i, pre);
    }
    // for(int j=0;j<n;j++){
    //     printf("%s\n", NR[j]);
    // }
    // HeapSort(H);
    // while(!IsEmpty(H)){
    //     int Order = DeleteMin(H);
    //     printf("%d\n", MinDataRes);
    //     HeapSort(H);
    // }
    HeapSort(H);
    for(int i = 0; i<m ; i++){
        int tempOrder = DeleteMin(H);
        int tempData = MinDataRes;
        int nextOrder;
        while(!IsEmpty(H)){
            //考虑优先级相同时的内容
            nextOrder = DeleteMin(H);
            if(tempOrder == nextOrder){
                if(NR[tempData]>NR[MinDataRes]){//输出的ascll值比同优先级的大
                    Insert(H, tempData, tempOrder);
                    tempOrder = nextOrder;
                    tempData = MinDataRes;
                }
                else{
                    Insert(H, MinDataRes, nextOrder);
                }
            }
            else{
                Insert(H, MinDataRes, nextOrder);
                break;
            }
            
        }
        printf("%s\n", NR[tempData]);
        Insert(H, tempData, tempOrder+tempOrder);
        HeapSort(H);
        // while(!IsEmpty(H)){
        //     printf("%d\n", DeleteMin(H));
        // }
    }
    return 0;
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

a9c93f2300

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值