- #include<istream>
- #include<string.h>
- #include<iomanip.h>
- using namespace std;
- const int maxJob=10;//定义空闲分区和已分配分区数组个数的最大值都为10
- typedef struct node
- {
- int start;//起始地址
- int length;//一个空闲区或已分配区的长度
- char tag[20];
- }job; //类型定义,定义job代替struct node类型
- job freetable[maxJob];//定义空闲区表
- int free_quantity; //空闲区个数
- job occupys[maxJob]; //定义已分配区表
- int occupy_quantity; //已分配区个数
- void initial(int a) //定义初始化函数
- {
- occupys[0].start=20;
- occupys[0].length=32;
- strcpy(occupys[0].tag,"A");
- occupys[1].start=52;
- occupys[1].length=20;
- strcpy(occupys[1].tag,"B");
- occupys[2].start=98;
- occupys[2].length=40;
- strcpy(occupys[2].tag,"C");
- occupys[3].start=148;
- occupys[3].length=22;
- strcpy(occupys[3].tag,"D");
- if(a==1) //最先适应算法时的空闲表
- {
- freetable[0].start=72;
- freetable[0].length=26;
- strcpy(freetable[0].tag,"free"); //长度为 26
- freetable[1].start=138;
- freetable[1].length=10;
- strcpy(freetable[1].tag,"free"); //长度为 10
- freetable[2].start=170;
- freetable[2].length=86;
- strcpy(freetable[2].tag,"free"); //长度为 86
- free_quantity=3;
- occupy_quantity=4;
- }
- if(a==2)//最优适应算法时的空闲表
- {
- freetable[0].start=138;
- freetable[0].length=10;
- strcpy(freetable[0].tag,"free");
- freetable[1].start=72;
- freetable[1].length=20;
- strcpy(freetable[1].tag,"free");
- freetable[2].start=170;
- freetable[2].length=86;
- strcpy(freetable[2].tag,"free");
- free_quantity=3;
- occupy_quantity=4;
- }
- if(a==3)//最差适应算法时的空闲表
- {
- freetable[0].start=170;
- freetable[0].length=86;
- strcpy(freetable[0].tag,"free");
- freetable[1].start=72;
- freetable[1].length=26;
- strcpy(freetable[1].tag,"free");
- freetable[2].start=138;
- freetable[2].length=10;
- strcpy(freetable[2].tag,"free");
- free_quantity=3;
- occupy_quantity=4;}
- }
- void view() //显示函数
- {
- int i; //自增变量i
- //输出当前空闲表
- cout<<endl<<"========================================================="<<endl;
- cout<<"当前空闲表:"<<endl;
- cout<<"起始地址 长度 状态"<<endl;
- for(i=0;i<free_quantity;i++)
- {
- //cout.setf(2);
- cout.width(12); //用width()函数更改当前的宽度设置。width()函数仅影响下一个显示项。之后,域宽度恢复成默认值。
- cout<<freetable[i].start;
- cout.width(10);
- cout<<freetable[i].length;
- cout.width(8);
- cout<<freetable[i].tag<<endl;
- }
- cout<<endl<<"当前总共有"<<free_quantity<<"个空闲区"<<endl;
- //输出当前已分配表
- cout<<endl<<"----------------------------------------------------------"<<endl;
- cout<<"当前已分配表:"<<endl;
- cout<<"起始地址 长度 占用作业名"<<endl;
- for(i=0;i<occupy_quantity;i++)
- {
- //cout.setf(2);
- cout.width(12);
- cout<<occupys[i].start;
- cout.width(10);
- cout<<occupys[i].length;
- cout.width(8);
- cout<<occupys[i].tag<<endl;
- }
- cout<<endl<<"当前总共有"<<occupy_quantity<<"个已分配区"<<endl;
- }//end view()
- //---------------------------------------最先适应分配算法---------------
- void earliest()
- {
- char job_name[20];//新建作业名
- int job_length;//新建作业名的长度
- cout<<"请输入新申请内存空间的作业名和空间大小(最先适应):";
- cin>>job_name;//输入新作业的名字
- cin>>job_length;//输入新作业的长度
- int i,flag=0; //flag是作为作业有没装入内存的标志,i作为数组元素的下标
- for(i=0;i<free_quantity;i++)//顺序查找现存的空闲区,有没大于新作业大小的,如果有,就置flag为1 :能够装的下
- {
- if(freetable[i].length>=job_length)
- flag=1; //如果有能放得下的空闲区,把flag置1,说明此作业已经被放入内存中
- }
- if(flag==0)
- {
- cout<<endl<<"Sorry,当前没有能满足你申请长度的空闲内存,请稍候再试"<<endl;
- }
- else//下面情况是当发现适合的空闲区之后系统要做的操作
- {
- int t=0;
- i=0;
- while(t==0)//此while循环是判断当发现有装得下新作业的空闲区之后就不再搜索后面的空闲区,有发现适合的空闲区,t置1
- {
- if(freetable[i].length>=job_length)
- {
- t=1;
- }
- i++;
- }
- //下面进行初始化新装入的作业
- i--; //为所发现的适合空闲区的数组元素(freetable[i])做准备,因为数组下标是从0开始,所以要减1
- occupys[occupy_quantity].start=freetable[i].start;//把发现的空闲区的起始地址变为新的已分配数组元素的起始地址
- strcpy(occupys[occupy_quantity].tag,job_name);//把新的已分配数组元素的名字变为新作业的名字
- occupys[occupy_quantity].length=job_length;//把新的已分配数组元素的长度变为新作业的长度
- occupy_quantity++;//把已分配区的个数加一
- if(freetable[i].length>job_length)//如果所找到的能存放新作业的空闲区的长度大于新作业的长度
- {
- freetable[i].start+=job_length;//把这个空闲区的起始地址变后移新作业长度的距离
- freetable[i].length-=job_length;//把这个空闲区的长度减去新作业的长度
- }
- else//下面的情况是所找到的空闲区的长度刚好等于新作业的长度的情况
- { int j;
- for(j=i;j<free_quantity-1;j++)
- {
- freetable[j]=freetable[j+1];
- }
- free_quantity--;
- cout<<endl<<"空闲区刚好被完全利用!"<<endl;
- }
- }
- }
- //--------------------------------------最优适应分配算法------------------
- void excellent()
- {
- char job_name[20];//新建作业名
- int job_length; //新建作业名的长度
- cout<<"请输入新申请内存空间的作业名和空间大小(最优适应):";
- cin>>job_name;//输入新作业的名字
- cin>>job_length;//输入新作业的长度
- int i,flag=0;//flag是作为作业有没装入内存的标志,i作为数组元素的下标
- for(i=0;i<free_quantity;i++)//顺序查找现存的空闲区,有没大于新作业大小的,如果有,就置flag为1
- {
- if(freetable[i].length>=job_length)
- flag=1; //如果有能放得下的空闲区,把flag置1,说明此作业已经被放入内存中
- }
- if(flag==0)
- {
- cout<<endl<<"Sorry,当前没有能满足你申请长度的空闲内存,请稍候再试"<<endl;
- }
- else
- {
- int t=0;
- i=0;
- while(t==0)
- {
- if(freetable[i].length>=job_length)//为下面的i做准备
- {
- t=1;
- }
- i++;
- }
- i--;//为所发现的适合空闲区的数组元素(freetable[i])做准备,因为数组下标是从0开始,所以要减1
- //下面是最优算法的关键代码
- int j;
- for(j=0;j<free_quantity;j++)
- {
- if((freetable[j].length>=job_length)&&(freetable[j].length<freetable[i].length))
- {
- i=j;
- }
- } //此循环结束之后j已经遍历所有空闲区找到一个最小的且能适合放新作业的空闲区freetable[i]
- occupys[occupy_quantity].start=freetable[i].start;//把发现的空闲区的起始地址变为新的已分配数组元素的起始地址
- strcpy(occupys[occupy_quantity].tag,job_name);//把新的已分配数组元素的名字变为新作业的名字
- occupys[occupy_quantity].length=job_length;//把新的已分配数组元素的长度变为新作业的长度
- occupy_quantity++;//把已分配区的个数加一
- if(freetable[i].length>job_length)
- {
- freetable[i].start+=job_length;
- freetable[i].length-=job_length;
- }
- else
- {
- for(j=i;j<free_quantity-1;j++)
- {
- freetable[j]=freetable[j+1];
- }
- free_quantity--;
- cout<<endl<<"空闲区刚好被完全利用!"<<endl;
- }
- }
- } //end excellent()
- //-------------------------------------最坏适应算法-----------------------
- void worst()
- {
- char job_name[20]; //新建作业名
- int job_length;//新建作业名的长度
- cout<<"请输入新申请内存空间的作业名和空间大小(最坏适应):";
- cin>>job_name;
- cin>>job_length;
- int flag=0, i;
- for(i=0;i<free_quantity;i++)
- {
- if(freetable[i].length>=job_length)
- {
- flag=1;
- }
- }
- if(flag==0)
- {
- cout<<endl<<"Sorry,当前没有能满足你申请长度的空闲内存,请稍候再试"<<endl;
- }
- else
- {
- int t=0,i=0;
- while(t==0)
- {
- if(freetable[i].length>=job_length)
- {
- t=1;
- }
- i++;
- }
- i--;
- //下面代码是最坏适应算法的关键
- int j;
- for(j=0;j<free_quantity;j++)
- {
- if((freetable[j].length>=job_length)&&(freetable[j].length>freetable[i].length))
- {
- i=j;
- }
- }
- occupys[occupy_quantity].start=freetable[i].start;
- strcpy(occupys[occupy_quantity].tag,job_name);
- occupys[occupy_quantity].length=job_length;
- occupy_quantity++;
- if(freetable[i].length>job_length)
- {
- freetable[i].start+=job_length;
- freetable[i].length-=job_length;
- }
- else
- {
- for(j=i;j<free_quantity-1;j++)
- {
- freetable[j]=freetable[j+1];
- }
- free_quantity--;
- cout<<endl<<"空闲区刚好被完全利用!"<<endl;
- }
- }
- } //end worst()
- //-------------------------------------撤消作业函数------------------------
- void undoBlock()
- {
- char job_name[20];//要删除的作业名
- int i,j;
- cout<<"请输入要撤消的作业名:";
- cin>>job_name;
- int flag=-1;
- int start,length;
- for(i=0;i<occupy_quantity;i++)//按名顺序查找已有的已分配区,找出要删除的作业
- {
- if(!strcmp(occupys[i].tag,job_name))
- //如果if条件满足的话,
- //说明strcmp(occupys[i].tag,job_name)返回值为0,说明找到了,
- //条件是如够找到的话,就执行下面的语句
- {
- flag=i;
- start=occupys[i].start;//用start存放找到的要撤销的作业的起始地址
- length=occupys[i].length;//用length存放找到的要撤销的作业的长度
- }
- }
- int p=0;//如果要删除的作业无相邻的空闲区,则把p置0;如果有,则把p置1
- if(flag==-1)
- {
- cout<<"没有这个作业名"<<endl;
- }
- else//下面是找到的情况
- {
- //加入空闲表
- for(i=0;i<free_quantity;i++) //顺序查找空闲区表,并修改空闲区表
- {
- if((freetable[i].start+freetable[i].length)==start)//如果此要撤销的作业有上邻空闲区
- {
- if(((i+1)<free_quantity)&&(freetable[i+1].start==start+length))//如果此要撤销的作业也有下邻空闲区
- {
- freetable[i].length=freetable[i].length+freetable[i+1].length+length;
- for(j=i+1;j<free_quantity;j++)
- {
- freetable[j]=freetable[j+1];//后面的空闲区表前移
- }
- free_quantity--;
- p=1;
- }
- else//如果此要撤销的作业只有上邻空闲区
- {
- freetable[i].length+=length;
- p=1;
- }
- }
- if(freetable[i].start==(start+length))//如果此要撤销的作业只有下邻空闲区
- {
- freetable[i].start=start;//相当于 删掉此已分配空间块
- freetable[i].length+=length;
- p=1;
- }
- }
- if(p==0)//如果要删除的作业无相邻的空闲区
- {
- freetable[free_quantity].start=start;
- freetable[free_quantity].length=length;
- free_quantity++;
- }
- //删除已分配表中的该作业
- for(i=flag;i<occupy_quantity;i++)
- {
- occupys[i]=occupys[i+1];
- }
- occupy_quantity--;
- }//end else
- }//end finished()
- int main()
- {
- int t=1;
- int chioce=0;
- int flag=1;
- int a;
- state:
- cout<<endl<<endl<<"========================================================="<<endl;
- cout<<endl<<endl;
- cout<<"┏━━━━━━━━━━━━━━━━━━━━━━━┓"<<endl;
- cout<<"┃ 算法模拟 ┃"<<endl;
- cout<<"┣━━━━━━━━━━━━━━━━━━━━━━━┫"<<endl;
- cout<<"┃ 实现 ┃"<<endl;
- cout<<"|_______________________________________________|"<<endl;
- cout<<endl<<endl;
- cout<<"========================================================="<<endl;
- cout<<"请选择要采用的算法"<<endl<<endl;
- cout<<"1.最先适应算法 "<<endl<<"2.最优适应算法"<<endl<<"3.最差适应算法"<<endl;
- cout<<"----------------------------------------------------------"<<endl;
- cout<<"请选择:";
- cin>>a;
- while(a<1||a>3)
- {
- cout<<"选择错误!请选择1-3之间的整数!"<<endl<<"请重新输入:";
- cin>>a;
- }
- initial(a);
- while(flag==1)
- {
- cout<<endl<<endl<<"========================================================="<<endl<<endl;
- cout<<"请选择要进行的操作:"<<endl<<endl<<"1.显示空闲表和分配表" <<endl
- <<"2.撤消作业" <<endl<<"3.申请空间"<<endl<<"0.退出"<<endl<<endl;
- cout<<"----------------------------------------------------------"<<endl;
- cout<<"请选择:";
- cin>>chioce;
- switch(chioce)
- {
- case 3:
- switch(a)
- {
- case 1: earliest(); break;
- case 2: excellent();break;
- case 3: worst();break;
- } // end switch(a)
- break;
- case 2:
- undoBlock();
- break;
- case 1:
- view();
- break;
- case 0:
- goto state;
- break;
- default:
- cout<<"选择错误!请重新输入"<<endl;
- }//end switch(chioce)
- }//end while()
- }//end mian()