思路:采用链表管理,利用伙伴关系,即控制empty表和work表的内存总和刚好等于此片内存区域大小
对每一种添加程序的算法,在执行前,先对empty表按照相应要求进行重排序,即:
1.最佳适应:empty表按照内存区域大小从小到大排序
2.首次适应:empty表按照内存首地址大小从小到大排序
3.最坏适应:empty表按照内存区域大小从大到小排序
对于回收内存时的上下连接检查:在checkAdress函数中进行,若存在连接区域,则对empty链表节点进行删除和修改
算法本身不难,主要是搞清楚三种算法的要求,笔者对于数组的使用很不习惯, 所以使用的是链表,大家也可以用数组活着别的数据结构形式改写,另外笔者排版上有点儿丑,很难受,代码量不大,仔细思考构思框架以后对于初学者基本半天以内解决。
尊重原创,转载注明出处:https://blog.csdn.net/kr2563
// Exercise3.cpp: 定义控制台应用程序的入口点。
//
/*
思路:采用链表管理,利用伙伴关系,即控制empty表和work表的内存总和刚好等于此片内存区域大小
对每一种添加程序的算法,在执行前,先对empty表按照相应要求进行重排序,即:
1.最佳适应:empty表按照内存区域大小从小到大排序
2.首次适应:empty表按照内存首地址大小从小到大排序
3.最坏适应:empty表按照内存区域大小从大到小排序
对于回收内存时的上下连接检查:在checkAdress函数中进行,若存在连接区域,则对empty链表节点进行删除和修改
*/
#include "stdafx.h"
#include
#include
#define yz 2 //定义阈值为2
using namespace std;
int sum = 0; //记录内存区域的整个大小
int alreadyUse = 0; //记录已经使用的内存区域大小
/*定义内存结构体*/
struct space {
int begin; //起始地址
int length; //长度
string name; //程序的名字
space *next;
};
typedef space *Space;
/*初始化, 此时empty起始地址为内存首地址,长度为整个内存区间,work表为空*/
void Init( Space empty, Space work, int length) {
empty->next = NULL;
work->next = NULL;
empty->begin = 0;
empty->length = length;
}
/*首次适应*/
void firstSuit(Space empty) {
space* temp1 = empty;
space* temp2 = empty;
if (empty == NULL)
return;
for (;temp1->next != NULL;temp1 = temp1->next)
{
for (temp2 = empty;temp2->next != NULL;temp2 = temp2->next)
{
if (temp2->begin > temp2->next->begin)
{
int temp = temp2->length;
int begin = temp2->begin;
temp2->length = temp2->next->length;
temp2->begin = temp2->next->begin;
temp2->next->length = temp;
temp2->next->begin = begin;
}
}
}
}
/*最坏适应*/
void worsestSuit(Space empty) {
space* temp1 = empty;
space* temp2 = empty;
if (empty == NULL)
return;
for (;temp1->next != NULL;temp1 = temp1->next)
{
for (temp2 = empty;temp2->next != NULL;temp2 = temp2->next)
{
if (temp2->length > temp2->next->length)
{
int temp = temp2->length;
int begin = temp2->begin;
temp2->length = temp2->next->length;
temp2->begin = temp2->next->begin;
temp2->next->length = temp;
temp2->next->begin = begin;
}
}
}
}
/*最好适应*/
void bestSuit(Space empty) {
space* temp1 = empty;
space* temp2 = empty;
if (empty == NULL)
return;
for (;temp1->next != NULL;temp1 = temp1->next)
{
for (temp2 = empty;temp2->next != NULL;temp2 = temp2->next)
{
if (temp2->length < temp2->next->length)
{
int temp = temp2->length;
int begin = temp2->begin;
temp2->length = temp2->next->length;
temp2->begin = temp2->next->begin;
temp2->next->length = temp;
temp2->next->begin = begin;
}
}
}
}
/*根据程序添加的方式对empty链表进行排序*/
void sortBychoice(Space empty, int choice) {
switch (choice)
{
case 1:
firstSuit(empty);
break;
case 2:
worsestSuit(empty);
break;
case 3:
bestSuit(empty);
break;
default:
cout << "* 未知的选择,默认当前选择! *" << endl;
break;
}
}
/*遍历打印empty表*/
void displayEmpty(Space empty) {
cout << endl << endl << "* empty *" << endl << endl;
if (empty == NULL) {
cout << "* 无可申请空间! *" << endl;
return;
}
space *temp = new space;
temp = empty;
cout << "begin" << "\t" << "length" << "\t" << "状态" << endl;
while (temp) {
cout << temp->begin << "\t" << temp->length << "\t" << "未分配" << endl;
temp = temp->next;
}
cout << endl;
}
/*遍历打印work表*/
void displayWork(Space work) {
cout << endl << endl << "* work *" << endl << endl;
if (work == NULL) {
cout << "* 无可回收内存! *" << endl;
return;
}
space *temp = new space;
temp = work->next;
cout << "begin" << "\t" << "length" << "\t" << "程序名" << endl;
while (temp) {
cout << temp->begin << "\t" << temp->length <<"\t" << temp->name.c_str() << endl;
temp = temp->next;
}
}
/*添加新的程序*/
void Create(Space empty, Space work) {
int choice;
int length;
int m = 0;
char name[10];
cout << "* 请选择添加算法 : *" << endl;
cout << "* 1: 首次适应算法 *" << endl;
cout << "* 2: 最佳适应算法 *" << endl;
cout << "* 3: 最坏适应算法 *" << endl;
cin >> choice;
sortBychoice(empty, choice);
displayEmpty(empty);
cout << "* 输入程序需要的长度: ";
cin >> length;
if (length > sum - alreadyUse) {
cout << "* 当前剩余存储区域不足以满足需求,拒绝继续添加程序" << endl;
return;
}
cout << "* 输入申请内存的程序名: ";
cin >> name;
space *temp = new space;
space *preTemp = new space;
preTemp = empty;
temp = empty;
while (temp) {
if (temp->length > length) {
//若差值小于阈值
if (temp->length - length <= yz) {
//判断是否是第一个结点
if (temp == empty) {
space *prog = new space;
prog->begin = temp->begin;
prog->length = temp->length;
prog->name = (string)name;
space *workList = new space;
workList = work;
while (workList->next) {
workList = workList->next;
}
prog->next = workList->next;
workList->next = prog;
empty = empty->next;
}
else {
space *prog = new space;
preTemp->next = temp->next;
prog->begin = temp->begin;
prog->length = temp->length;
prog->name = (string)name;
space *workList = new space;
workList = work;
while (workList->next) {
workList = workList->next;
}
prog->next = workList->next;
workList->next = prog;
}
}
else {
space *prog = new space;
prog->begin = temp->begin;
prog->length = length;
temp->begin = temp->begin + length;
temp->length = temp->length - length;
prog->name = (string)name;
space *workList = new space;
workList = work;
while (workList->next) {
workList = workList->next;
}
prog->next = workList->next;
workList->next = prog;
}
break;
}
temp = temp->next;
if (m == 1)
preTemp = preTemp->next;
m = 1;
}
displayWork(work);
cout << endl;
displayEmpty(empty);
}
/*统计empty表长度*/
int getLength(Space empty) {
int length = 0;
space *temp = new space;
temp = empty;
while (temp)
{
length++;
temp = temp->next;
}
return length;
}
/*检查地址*/
void checkAddress(Space empty) {
space *temp = new space;
space *preTemp = new space;
temp = empty;
while (temp) {
if (temp->next) {
if (temp->begin + temp->length == temp->next->begin) {
temp->length = temp->length + temp->next->length;
temp->next = temp->next->next;
}
}
temp = temp->next;
}
preTemp = empty;
temp = preTemp->next;
//对末尾结点的检查
while (temp) {
if (temp->next == NULL) {
if (temp->begin == preTemp->begin + preTemp->length) {
preTemp->length = preTemp->length + temp->length;
preTemp->next = NULL;
break;
}
}
temp = temp->next;
preTemp = preTemp->next;
}
}
/*回收已有的程序*/
void callBack(Space empty, Space work) {
string name;
int len;
int begin;
int length;
int flag = 0; //用于判断输入是否正确
displayWork(work);
cout << "* 输入将要回收的程序名: ";
cin >> name;
space *tempWork = new space;
space *preTempwork = new space;
space *tempEmpty = new space;
tempWork = work->next;
preTempwork = work;
tempEmpty = empty;
while (tempWork) {
if (!tempWork->name.compare(name)){
flag = 1; //寻找到目标程序
begin = tempWork->begin;
length = tempWork->length;
len = getLength(empty);
preTempwork->next = tempWork->next; //从work表中删除该节点
while (tempEmpty){
space *newEmpty = new space;
newEmpty->begin = begin;
newEmpty->length = length;
newEmpty->name = "未分配";
if (len >= 2) {
if (tempEmpty->begin > begin) {
newEmpty->begin = tempEmpty->begin;
newEmpty->length = tempEmpty->length;
tempEmpty->begin = begin;
tempEmpty->length = length;
newEmpty->next = tempEmpty->next;
tempEmpty->next = newEmpty;
break;
}
}
else {
if (begin < tempEmpty->begin) {
newEmpty->begin = tempEmpty->begin;
newEmpty->length = tempEmpty->length;
tempEmpty->begin = begin;
tempEmpty->length = length;
newEmpty->next = tempEmpty->next;
tempEmpty->next = newEmpty;
}
else {
newEmpty->next = tempEmpty->next;
tempEmpty->next = newEmpty;
}
break;
}
tempEmpty = tempEmpty->next; //这里不在第一次查询到就break是因为程序可能被分段存储的
}
}
tempWork = tempWork->next;
preTempwork = preTempwork->next;
}
if (flag == 0)
cout << "未查询到将要回收的程序段,请重新选择!" << endl;
else {
//合并内存
firstSuit(empty);
checkAddress(empty);
}
displayWork(work);
displayEmpty(empty);
}
int main()
{
int choice, length;
Space empty, work;
empty = new space;
work = new space;
cout << "输入最大的内存容量: ";
cin >> length;
sum = length; //将整体的长度赋值给全局变量
Init(empty, work, length); // empty ---> 空闲的区域 work ---> 装入程序的区域
while (1) {
cout << "*************************" << endl;
cout << "* 1:添加作业 *" << endl;
cout << "* 2:回收内存 *" << endl;
cout << "* 3:退出程序 *" << endl;
cout << "* 请选择: *" << endl;
cin >> choice;
switch (choice) {
case 1:
Create(empty, work);
break;
case 2:
callBack(empty, work);
break;
case 3:
cout << "* 谢谢使用! *" << endl;
exit(0);
}
}
return 0;
}