純c語言寫動態分割槽分配演算法的FirstFit和BestFit
阿新 • • 發佈:2019-01-02
主要參考連結:
動態分割槽分配:
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
個人感想:動態分割槽分配和另外兩個有點不一樣,一開始看到的時候對它的資料結構有點懵。
主要的資料結構(記憶體空閒分割槽的地址直接用陣列順序儲存了,地址大小順序按照陣列下標
#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的結果