POJ1193, 内存分配

链接:http://poj.org/problem?id=1193

用链表模拟内存分配,维护一个等待队列和两个链表,一个链表记录空闲内存,另一个记录待释放的内存块。由于木有用stl,写的灰常繁琐。。。

Memory: 628K    Time: 688MS

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#define true 1
#define false 0

typedef int queueType;
typedef int listType;

//进程控制块
typedef struct _proCb
{
    int applyTime;
    int applyMem;
    int applyPeriod;
    int addr;
    int freeTime;
}proCb;

//队列节点
typedef struct _queueNode
{
    queueType data;
    struct _queueNode *pNext;
}queueNode;

//队列
typedef struct _linkQueue
{
    queueNode *pFront;
    queueNode *pRear;
}linkQueue;

//链表节点
//保存待释放内存时,key为释放时间,data为占用该内存块的进程id
//保存空闲内存时,key为内存块地址,data为内存块大小
typedef struct _listNode
{
    int key;
    listType data;
    struct _listNode *pNext;
}listNode;

//链表
typedef struct _linkList
{
    listNode *pHead;
    int count;
}linkList;

//构造一个空队列
linkQueue *initQueue()
{
    linkQueue *pQueue = (linkQueue *)malloc(sizeof(linkQueue));
    if (pQueue != NULL)
    {
        pQueue->pFront = NULL;
        pQueue->pRear = NULL;
    }
    return pQueue;
}

//创建一个新队列结点
queueNode *initQueueNode(queueType data)
{
    queueNode *pQNode = (queueNode *)malloc(sizeof(queueNode));
    if (pQNode != NULL)
    {
        pQNode->data = data;
        pQNode->pNext = NULL;
    }
    return pQNode;
}

//判断队列是否为空
int isEmpty(linkQueue *pQueue)
{
    if (pQueue->pFront == NULL)
        return true;
    return false;
}

//入队
void enQueue(linkQueue *pQueue, queueNode *pNode)
{
    if (pQueue->pFront == NULL)
    {
        pQueue->pFront = pNode;
        pQueue->pRear = pNode;
    }
    else
    {
        pQueue->pRear->pNext = pNode;
        pQueue->pRear = pNode;
    }
}

//出队
void deQueue(linkQueue *pQueue)
{
    queueNode *pFront = NULL;
    if (!isEmpty(pQueue))
    {
        pFront = pQueue->pFront;
        pQueue->pFront = pFront->pNext;
        free(pFront);
    }
}

//创建新的链表节点
listNode *initListNode(int key, listType data)
{
    listNode *pNode;
    pNode = (listNode *)malloc(sizeof(listNode));
    if (pNode != NULL)
    {
        pNode->key = key;
        pNode->data = data;
        pNode->pNext = NULL;
    }
    return pNode;
}

//删除链表中的某一个节点
listNode *getListNode(linkList *pList, listNode *pPre, listNode *pTemp)
{
    if (pPre == NULL)
        pList->pHead = pTemp->pNext;
    else
        pPre->pNext = pTemp->pNext;
    pList->count--;
    return pTemp;
}

//构造一个空链表
linkList *initList(void)
{
    linkList *pList;
    pList = (linkList *)malloc(sizeof(linkList));
    if (pList != NULL)
    {
        pList->pHead = NULL;
        pList->count = 0;
    }
    return pList;
}

//初始化内存
linkList *initMem(int memSize)
{
    linkList *pList;
    listNode *pNode;
    pList = (linkList *)malloc(sizeof(linkList));
    if (pList != NULL)
    {
        pNode = initListNode(0, memSize);
        pList->pHead = pNode;
        pList->count = 1;
    }
    return pList;
}

//链表插入排序
void insertSort(linkList *pList, listNode *pNode)
{
    listNode *pTemp, *pPre;

    pTemp = pList->pHead;
    if (pTemp == NULL)
        pList->pHead = pNode;
    else if(pNode->key < pTemp->key)
    {
        pNode->pNext = pTemp;
        pList->pHead = pNode;
    }
    else
    {
        while (pTemp != NULL)
        {
            if (pNode->key < pTemp->key)
                break;
            pPre = pTemp;
            pTemp = pTemp->pNext;
        }
        pNode->pNext = pTemp;
        pPre->pNext = pNode;
    }
    pList->count++;
}

//删除链表的头节点
void rmList(linkList *pList)
{
    listNode *pTemp = pList->pHead; 
    pList->pHead = pTemp->pNext;
    pList->count--;
    free(pTemp);
}

//内存分配
int allocMem(linkList *memory, proCb *pPro, int timer)
{
    listNode *pPre = NULL, *pTemp = memory->pHead;
    
    while (pTemp != NULL)
    {
        if (pTemp->data >= pPro->applyMem)   //有可分配的内存
        {
            pPro->addr = pTemp->key;
            pPro->freeTime = timer + pPro->applyPeriod;
            getListNode(memory, pPre, pTemp);
            pTemp->key += pPro->applyMem;
            pTemp->data -= pPro->applyMem;
            if (pTemp->data > 0)
                insertSort(memory, pTemp);
            else
                free(pTemp);
            return true;
        }
        pPre = pTemp;
        pTemp = pTemp->pNext;
    }
    return false;
}

//内存释放
void freeMem(linkList *memory, proCb *pPro)
{
    listNode *pPre = NULL, *pTemp = memory->pHead;
    listNode *pFree = initListNode(pPro->addr, pPro->applyMem);
    
    while (pTemp != NULL)   //若有相连的内存则合并起来
    {
        if ((pTemp->key + pTemp->data == pFree->key) || (pFree->key + pFree->data == pTemp->key)) //相连
        {
            getListNode(memory, pPre, pTemp);
            pFree->data += pTemp->data;
            if (pTemp->key + pTemp->data == pFree->key) //pFree在pTemp后面
                pFree->key = pTemp->key;
            free(pTemp);
            pPre = NULL;
            pTemp = memory->pHead;
        }
        else
        {
            pPre = pTemp;
            pTemp = pTemp->pNext;
        }
    }

    insertSort(memory, pFree);
    
}
proCb process[10000] = {0};

int main(void)
{
    int memSize;
    int proNum = 0; //进程数
    int timer = -1;  //模拟定时器
    int proId;      //进程号,即进程数组的下标值
    int handleProId = 0;    //已处理到的进程id
    int waitedCount = 0;    //记录被放入等待队列的进程总数
    linkQueue *applyQueue;  //等待队列
    linkList *freeList;     //待释放链表
    linkList *memory;        //空闲内存
    queueNode *pQueueNode;
    listNode *pListNode;

    scanf("%d", &memSize);
    memory = initMem(memSize);
    
    while (1)
    {
        scanf("%d%d%d", &process[proNum].applyTime, &process[proNum].applyMem, &process[proNum].applyPeriod);
        if (process[proNum].applyTime == 0 && process[proNum].applyMem == 0 && process[proNum].applyPeriod == 0)
            break;
        proNum++;
    }

    applyQueue = initQueue();
    freeList = initList();

    while (1)
    {
        ++timer;
        if ((freeList->count == 0) && (isEmpty(applyQueue)) && (handleProId == proNum)) //处理完毕
            break;
        while (freeList->count > 0) //同一时刻可能会释放多块内存
        {
            pListNode = freeList->pHead;
            proId = pListNode->data;
            if (process[proId].freeTime != timer)
                break;
            else
            {
                freeMem(memory, &process[proId]);
                rmList(freeList);
            }
        }
        while (!isEmpty(applyQueue))
        {
            proId = applyQueue->pFront->data;
            if (allocMem(memory, &process[proId], timer))
            {
                insertSort(freeList, initListNode(process[proId].freeTime, proId));
                deQueue(applyQueue);
            }
            else
                break;
        }
        while ((handleProId < proNum) && (process[handleProId].applyTime == timer))  //同一时刻可能有多个进程申请内存
        {
            if (allocMem(memory, &process[handleProId], timer))
            {
                insertSort(freeList, initListNode(process[handleProId].freeTime, handleProId));
            }
            else
            {
                pQueueNode = initQueueNode(handleProId);
                enQueue(applyQueue, pQueueNode);
                waitedCount++;
            }
            handleProId++;
        }
    }
    printf("%d\n%d\n", --timer, waitedCount);
    
    free(memory);
    free(freeList);
    free(applyQueue);
    
    system("pause");
    return 0;
}
 

posted on 2012-07-09 22:54  lltctt  阅读(237)  评论(0)    收藏  举报

导航