1. 程式人生 > >純c語言寫動態分割槽分配演算法的FirstFit和BestFit

純c語言寫動態分割槽分配演算法的FirstFit和BestFit

主要參考連結:

動態分割槽分配:

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

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

 

1.程序排程演算法FCFS和RR

2.作業排程演算法SJF,HRRN

3.動態分割槽分配演算法的FirstFit和BestFit

 

個人感想:動態分割槽分配和另外兩個有點不一樣,一開始看到的時候對它的資料結構有點懵。

 

主要的資料結構(記憶體空閒分割槽的地址直接用陣列順序儲存了,地址大小順序按照陣列下標

#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的結果