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; }
浙公网安备 33010602011771号