纯c语言写动态分区分配算法的FirstFit和BestFit

主要参考链接:

动态分区分配:

https://blog.csdn.net/houchaoqun_xmu/article/details/55541299

https://blog.csdn.net/cm_cyj_1116/article/details/53518790

[声明]本文为转载是因为代码大多数都是网上copy的,然后自己也只是微调加实现过,个人认为不可以当原创。代码全部都贴上来了,txt文档的格式也贴了,也实现过,如果期间遇到困难,希望你们再去找其他的资料,问我的话我未必能答上来。

 

操作系统系列文章:

1.进程调度算法FCFS和RR

2.作业调度算法SJF和HRRN

3.动态分区分配算法的FirstFit和BestFit

4.银行家算法

 

个人感想:动态分区分配和另外两个有点不一样,一开始看到的时候对它的数据结构有点懵。

 

主要的数据结构(内存空闲分区的地址直接用数组顺序存储了,地址大小顺序按照数组下标

#define MAXNUMBER 100
static int MinPartitionNum;//事先规定的不再切割的剩余分区的大小 
static int PartitionNum;  //内存中空闲分区的个数
static int ProcessNum; //需要分配的进程个数
static int FreePartition[MAXNUMBER];  //空闲分区对应的内存
static int ProcessNeed[MAXNUMBER];  //需要分配的进程大小
 
static int LeftFreePartition[MAXNUMBER];
//static int LeftProcessNeed[MAXNUMBER];//参考链接有这个,但我不知道什么来的就没要它了 
 
static char ProcessName[MAXNUMBER];
static char NameProcessToPartition[MAXNUMBER][MAXNUMBER];
 
struct free_node//这个用在BestFit算法里
{
	int partitionSize;
	int id;
};

用到的函数

void readDataFunction();//向文本读入数据
void initial();//初始化
void FirstFit();
void BestFit();
void sort(free_node *p,int PartitionNum);//BestFit所需要的排序
void display();//显示最终结果 
void display_sort(free_node *p,int PartitionNum);//具体显示BestFit的排序 
void display_insert(); //显示输入的数据 

核心算法

void FirstFit()
{
	printf("***********首次适应算法***********\n"); 
	initial();
    display_insert();
	 
	int i,j;
	for (i = 0;i<ProcessNum;i++)   //逐个遍历每个进程
	{
		for (j = 0;j<PartitionNum;j++)   //每次都从分区的首地址开始查找
		{
			if (ProcessNeed[i] <= (LeftFreePartition[j]-MinPartitionNum) && LeftFreePartition!=0)  //进程需要的资源要<=空闲分区大小-事先规定的不再切割的剩余分区的大小

			{
				LeftFreePartition[j] -= ProcessNeed[i];   //扣除分配给进程的资源
				NameProcessToPartition[i][j] = ProcessName[i];  //存储各个进程所在的分区位置
				break;   //!!!很重要,一个进程分区完后,应该立即break,进行下一个进程的判断
			}
		}
	}
 
	display();
	
}
//思想:利用冒泡排序对分区大小进行排序,但不改变原分区的位置
void sort(free_node *p,int PartitionNum)//对内存容量进行从小到大的排序(BestFit要用到的
{ 
	for(int i=0;i<PartitionNum;i++)
		for(int j=i+1;j<PartitionNum;j++)
	      if(p[i].partitionSize>p[j].partitionSize)
         {
	      	free_node temp;
	      	temp=p[i];
	      	p[i]=p[j];
	      	p[j]=temp;
         }
}
void BestFit()
{
	//创建一个结构体,包括分区大小和所对应的id,排序过程中,每改变顺序一次,id随着改变
	//关键:每次分配完一个进程的内存大小后,都要重新排序
	printf("***********最佳适应算法***********\n"); 
	initial();
	display_insert();
	
	int i,j;

	free_node best[MAXNUMBER];

	for (i = 0;i<PartitionNum;i++)
	{
		//初始化结构体
		best[i].partitionSize = FreePartition[i];
		best[i].id = i;
	}
    
	for (i = 0;i<ProcessNum;i++)
	{
        sort(best,PartitionNum);
        printf("\n第%d次排序:       ",i+1);
        display_sort(best,PartitionNum);
		  
	for (j = 0;j<PartitionNum;j++)
		{
//			if (ProcessNeed[i] <= best[j].partitionSize)//没有“剩余分区最小不少于”的限制 
			if(ProcessNeed[i] <= (best[j].partitionSize-MinPartitionNum) && best[j].partitionSize!=0)
			{
				best[j].partitionSize -= ProcessNeed[i];
				NameProcessToPartition[i][best[j].id] = ProcessName[i];
				break;
			}
		}
		
		LeftFreePartition[best[j].id] = best[j].partitionSize;
	}
	display();
}

测试数据的输入 

源代码

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

#define MAXNUMBER 100
static int MinPartitionNum;//事先规定的不再切割的剩余分区的大小 
static int PartitionNum;  //内存中空闲分区的个数
static int ProcessNum; //需要分配的进程个数
static int FreePartition[MAXNUMBER];  //空闲分区对应的内存
static int ProcessNeed[MAXNUMBER];  //需要分配的进程大小
 
static int LeftFreePartition[MAXNUMBER];
//static int LeftProcessNeed[MAXNUMBER];//没要它了 
 
static char ProcessName[MAXNUMBER];
static char NameProcessToPartition[MAXNUMBER][MAXNUMBER];
 
struct free_node
{
	int partitionSize;
	int id;
};

void readDataFunction();//向文本读入数据
void initial();//初始化
void FirstFit();
void BestFit();
void sort(free_node *p,int PartitionNum);//BestFit所需要的排序
void display();//显示最终结果 
void display_sort(free_node *p,int PartitionNum);//具体显示BestFit的排序 
void display_insert(); //显示输入的数据 

void readDataFunction(){
	FILE *fp;
	fp=fopen("data.txt","r");
    if(fp==NULL){
		exit(EXIT_FAILURE);
	}
	fscanf(fp,"%d",&MinPartitionNum);
	fscanf(fp,"%d",&PartitionNum);
	for (int i=0;i<PartitionNum;i++)
	{
		fscanf(fp,"%d",&FreePartition[i]);
	}
	fscanf(fp,"%d",&ProcessNum);
	for (int i=0;i<ProcessNum;i++)
	{
		fscanf(fp," %c ",&ProcessName[i]);
	}
	for (int i=0;i<ProcessNum;i++)
	{
		fscanf(fp,"%d",&ProcessNeed[i]);
	}
	
}

void initial()
{
	readDataFunction();   //读取原始数据
	for (int i=0;i<ProcessNum;i++)
	{	
		for (int j =0;j<PartitionNum;j++)
		{
			NameProcessToPartition[i][j] =NULL;
			LeftFreePartition[j] = FreePartition[j];
		}
	}
}

void display_insert(){
	printf("剩余分区最小不少于:%d\n",MinPartitionNum);
	printf("需要分配内存的进程名:");
	for (int i = 0;i<ProcessNum;i++)
	{
		printf("       %c   ",ProcessName[i]);//仅仅为了输出好看而已 
	}

	printf("\n需要分配内存的进程分区大小:");
	for (int i = 0;i<ProcessNum;i++)
	{
		printf("%2d         ",ProcessNeed[i]);
	}
	printf("\n\n");
		
	printf("输入时的分区序号:");
	for (int i = 0;i<PartitionNum;i++)
	{
		printf("分区%d      ",i+1);
	}
	printf("\n分区大小:");
	for (int i = 0;i<PartitionNum;i++)
	{  
	    printf("         %2d",FreePartition[i]);
	}
	
}

void FirstFit()
{
	printf("***********首次适应算法***********\n"); 
	initial();
    display_insert();
	 
	int i,j;
	for (i = 0;i<ProcessNum;i++)   //逐个遍历每个进程
	{
		for (j = 0;j<PartitionNum;j++)   //每次都从分区的首地址开始查找
		{
			if (ProcessNeed[i] <= (LeftFreePartition[j]-MinPartitionNum) && LeftFreePartition!=0)  //当系统内存分区足够大的时候,即分配给进程资源
//			if (ProcessNeed[i] <= LeftFreePartition[j] && LeftFreePartition!=0)  //当系统内存分区足够大的时候,即分配给进程资源
			{
				LeftFreePartition[j] -= ProcessNeed[i];   //扣除分配给进程的资源
 
				NameProcessToPartition[i][j] = ProcessName[i];  //存储各个进程所在的分区位置
 
				break;   //!!!很重要,一个进程分区完后,应该立即break,进行下一个进程的判断
			}
		}
	}
 
	display();
	
}

void sort(free_node *p,int PartitionNum)//对内存容量进行从小到大的排序
{ 
	for(int i=0;i<PartitionNum;i++)
		for(int j=i+1;j<PartitionNum;j++)
	      if(p[i].partitionSize>p[j].partitionSize)
		  {
	      	free_node temp;
	      	temp=p[i];
	      	p[i]=p[j];
	      	p[j]=temp;
		  }
}

void display_sort(free_node *p,int PartitionNum)
{
	for (int i = 0;i<PartitionNum;i++)
      {
		 printf("分区%d      ",p[i].id+1);
	  }
	    printf("\n分区大小:");
	    
	    for (int i = 0;i<PartitionNum;i++)
	  {  
	     printf("         %2d",p[i].partitionSize);
	  }
}

void BestFit()
{
	//思想:利用冒泡排序对分区大小进行排序,但不改变原分区的位置
	//创建一个结构体,包括分区大小和所对应的id,排序过程中,每改变顺序一次,id随着改变
	//关键:每次分配完一个进程的内存大小后,都要重新排序
	printf("***********最佳适应算法***********\n"); 
	initial();
	display_insert();
	
	int i,j;
 
	free_node best[MAXNUMBER];
	
	for (i = 0;i<PartitionNum;i++)
	{
		//初始化结构体
		best[i].partitionSize = FreePartition[i];
		best[i].id = i;
	}
    
	for (i = 0;i<ProcessNum;i++)
	{
        sort(best,PartitionNum);
        printf("\n第%d次排序:       ",i+1);
        display_sort(best,PartitionNum);
		  		  
		for (j = 0;j<PartitionNum;j++)
		{
			if(ProcessNeed[i] <= (best[j].partitionSize-MinPartitionNum) && best[j].partitionSize!=0)
			{
				best[j].partitionSize -= ProcessNeed[i];
				NameProcessToPartition[i][best[j].id] = ProcessName[i];
				break;
			}
		}
		
		LeftFreePartition[best[j].id] = best[j].partitionSize;
	}
    printf("\n");
	display();
}

void display()
{
	int i;
    printf("\n分区序号:");

	for (i = 0;i<PartitionNum;i++)
	{
		printf("分区%d ",i+1);
	}
	printf("\n分区大小:");
	for (i = 0;i<PartitionNum;i++)
	{  
	    printf(" %4d ",FreePartition[i]);
	}
	printf("\n剩余大小:");
	for (i = 0;i<PartitionNum;i++)
	{
		printf(" %4d ",LeftFreePartition[i]);
	}
	printf("\n分配进程情况:\n");
	for (i = 0;i<PartitionNum;i++)
	{
		for (int j = 0;j<ProcessNum;j++)
		{
			if (NameProcessToPartition[j][i]!=NULL)
			{
				printf("%c:--->分区%d\n",NameProcessToPartition[j][i],i+1); 
			}		
		}	
	}
	printf("\n***************结束***************\n");
}


int main(void){	
	int a;
	printf("动态分区分配算法:1.FirstFit 2.BestFit 3.quit\n");
	scanf("%d",&a);
	while(a!=3){
	
	switch(a){
		case 1:
		FirstFit();
		break; 
		
		case 2:
		BestFit();
		break; 
		 
		case 3: 
		printf("end.\n");
		
		default:
		 break; 
	}
//    system("cls");
	printf("\n动态分区分配算法:1.FirstFit 2.BestFit 3.quit\n");
	scanf("%d",&a);
}
	
	return 0;
} 

 实验截图

FirstFit的结果

 BestFit的结果

  • 5
    点赞
  • 44
    收藏
    觉得还不错? 一键收藏
  • 4
    评论
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值