BestFit
package com.algorithm.dp_allocation;
import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;
/**
* @Class BestFit
* @Description 最佳适应算法
* @Author Naren
* @Date 2020/5/23 15:30
* @Version 1.0
*/
public class BestFit {
private static Scanner sc = new Scanner(System.in);
private static List<Block> blockList = new ArrayList<>();
/**
* 内部Block类,分区
*/
private static class Block {
int address; //分区首地址
int size; //分区大小
int id; //进程id
/*打印分区信息*/
public String toString(){
return String.format( "[%5d| %5d| %5d]", address, size, id );
}
}
/**
* 初始化分区
*/
private static void initBlock(){
BestFit.Block block = new BestFit.Block();
System.out.println("-----------最佳适应算法 BF----------\n\n");
System.out.println("请输入内存空间大小(KB):");
block.size = sc.nextInt();
block.address = 0;
block.id = -1;
blockList.add(block);
}
/**
* 寻找空闲分区并为新作业分配空间
* @param id
* @param size
*/
private static boolean allocation(int id, int size){
//分配成功与否的标志
boolean flag = false;
int blockAddress = 0;
int blockSize = 0;
int blockId = 0;
//标记最佳分区的位置
int mark = 0;
int min = 0;
int count = 0;
/*顺序遍历所有分区*/
// int min = blockList.get(0).size;
for(int i = 0; i < blockList.size(); i++){
blockAddress = blockList.get(i).address;
blockSize = blockList.get(i).size;
blockId = blockList.get(i).id;
/*若存在空闲且内存合适的分区,重新分配*/
if(blockId == -1 && blockSize >= size) {
count++;
if(count == 1) {
min = blockSize - size;
mark = i;
}else if(count > 1) {
if (min > blockSize - size) {
min = blockSize - size;
mark = i;
}
}
flag = true;
}
}
if(flag) {
blockAddress = blockList.get(mark).address;
blockSize = blockList.get(mark).size;
blockList.get(mark).id = id;
blockList.get(mark).size = size;
/*若当前分区重新分配后有剩余内存,
则将其作为新的分区并设置新的address 和 size*/
if (blockSize > size) {
BestFit.Block newBlock = new BestFit.Block();
newBlock.id = -1;
newBlock.address = blockAddress + size;
newBlock.size = blockSize - size;
blockList.add(mark + 1, newBlock);
}
}
//返回分配结果
return flag;
}
/**
* 释放内存并合并空闲分区
* @param id
*/
private static boolean release(int id) {
//释放成功与否的标志
boolean flag = false;
int blockId = 0;
int blockSize = 0;
for(int i = 0; i < blockList.size(); i++) {
blockId = blockList.get(i).id;
//释放成功
if (blockId == id) {
blockList.get(i).id = -1;
/*当分区为第一个时*/
if(i == 0){
//若与之相邻下一个分区空闲
if (blockList.get(i + 1).id == -1) {
/*更新本分区的size并删除下一分区*/
blockList.get(i).size += blockList.get(i + 1).size;
blockList.remove(i + 1);
}
}
/*当分区不是第一个也不是最后一个*/
else if(i < blockList.size() - 1) {
//若与之相邻上一个分区空闲且下一分区不空闲
if (blockList.get(i - 1).id == -1 && blockList.get(i + 1).id != -1) {
/*更新上一分区的size并删除本分区*/
blockList.get(i - 1).size += blockList.get(i).size;
blockList.remove(i);
}
//若与之相邻下一个分区空闲且上一分区不空闲
else if (blockList.get(i + 1).id == -1 && blockList.get(i - 1).id != -1) {
/*更新本分区的size并删除下一分区*/
blockList.get(i).size += blockList.get(i + 1).size;
blockList.remove(i + 1);
}
//若与之相邻上下分区都空闲
else if (blockList.get(i - 1).id == -1 && blockList.get(i + 1).id == -1) {
/*更新上一分区的size并删除本、下一分区*/
blockList.get(i - 1).size += blockSize;
blockList.get(i - 1).size += blockList.get(i + 1).size;
blockList.remove(i);
blockList.remove(i);
}
}
/*当分区为最后一个分区时*/
else if(i == blockList.size() - 1){
//若与之相邻上一个分区空闲
if (blockList.get(i - 1).id == -1) {
/*更新上一分区的size并删除本分区*/
blockList.get(i - 1).size += blockList.get(i).size;
blockList.remove(i);
}
}
flag = true;
break;
}
}
return flag;
}
/**
* 打印内存分配情况
*/
private static void show(List<BestFit.Block> blockList) {
int i = 0;
System.out.println(" 首地址 分区大小 作业id");
for(BestFit.Block block: blockList)
System.out.println(" 分区" + ++i + ":" + block);
System.out.println();
}
/**
* 操作面板
*/
private static void operator(){
String choose = "";
int id = 0;
int size = 0;
while(true) {
System.out.println("1.为新作业分配内存 2.作业完成释放内存");
System.out.println("3.查看当前内存分配 4.退出程序");
System.out.println("请输入待进行操作编号:");
choose = sc.next();
switch (choose) {
case "1":
System.out.println("作业id及申请空间大小:");
id = sc.nextInt();
size = sc.nextInt();
if (allocation(id, size))
System.out.println("内存分配成功。\n");
else
System.out.println("内存分配失败。\n");
break;
case "2":
System.out.println("待释放内存进程id:");
id = sc.nextInt();
if (release(id))
System.out.println("内存释放成功。\n");
else
System.out.println("内存释放失败。\n");
break;
case "3":
show(blockList);
break;
case "4":
System.exit(0);
}
}
}
/**
* main()
*/
public static void main(String[] args) {
initBlock();
operator();
}
}
FirstFit
package com.algorithm.dp_allocation;
import java.util.*;
/**
* @Class FirstFit
* @Description 首次适应算法
* @Author Naren
* @Date 2020/5/23 15:29
* @Version 1.0
*/
public class FirstFit {
private static Scanner sc = new Scanner(System.in);
private static List<Block> blockList = new ArrayList<>();
/**
* 内部Block类,分区
*/
private static class Block {
int address; //分区首地址
int size; //分区大小
int id; //进程id
/*打印分区信息*/
public String toString(){
return String.format( "[%5d| %5d| %5d]", address, size, id );
}
}
/**
* 初始化分区
*/
private static void initBlock(){
Block block = new Block();
System.out.println("-----------首次适应算法 FF----------\n\n");
System.out.println("请输入内存空间大小(KB):");
block.size = sc.nextInt();
block.address = 0;
block.id = -1;
blockList.add(block);
}
/**
* 寻找空闲分区并为新作业分配空间
* @param id
* @param size
*/
private static boolean allocation(int id, int size){
//分配成功与否的标志
boolean flag = false;
int blockAddress = 0;
int blockSize = 0;
int blockId = 0;
/*顺序遍历所有分区*/
for(int i = 0; i < blockList.size(); i++){
blockAddress = blockList.get(i).address;
blockSize = blockList.get(i).size;
blockId = blockList.get(i).id;
/*若存在空闲且内存合适的分区,重新分配*/
if(blockId == -1 && blockSize >= size) {
blockList.get(i).id = id;
blockList.get(i).size = size;
/*若当前分区重新分配后有剩余内存,
则将其作为新的分区并设置新的address 和 size*/
if (blockSize > size) {
FirstFit.Block newBlock = new Block();
newBlock.id = -1;
newBlock.address = blockAddress + size;
newBlock.size = blockSize - size;
blockList.add(i + 1, newBlock);
}
flag = true;
break;
}
}
//返回分配结果
return flag;
}
/**
* 释放内存并合并空闲分区
* @param id
*/
public static boolean release(List<Block> block_List, int id) {
//释放成功与否的标志
block_List = blockList;
boolean flag = false;
int blockId = 0;
int blockSize = 0;
for(int i = 0; i < block_List.size(); i++) {
blockId = block_List.get(i).id;
blockSize = block_List.get(i).size;
//释放成功
if (blockId == id) {
block_List.get(i).id = -1;
/*当分区为第一个时*/
if(i == 0){
//若与之相邻下一个分区空闲
if (block_List.get(i + 1).id == -1) {
/*更新本分区的size并删除下一分区*/
block_List.get(i).size += block_List.get(i + 1).size;
block_List.remove(i + 1);
}
}
/*当分区不是第一个也不是最后一个*/
else if(i < block_List.size() - 1) {
//若与之相邻上一个分区空闲且下一分区不空闲
if (block_List.get(i - 1).id == -1 && block_List.get(i + 1).id != -1) {
/*更新上一分区的size并删除本分区*/
block_List.get(i - 1).size += block_List.get(i).size;
block_List.remove(i);
}
//若与之相邻下一个分区空闲且上一分区不空闲
else if (block_List.get(i + 1).id == -1 && block_List.get(i - 1).id != -1) {
/*更新本分区的size并删除下一分区*/
block_List.get(i).size += block_List.get(i + 1).size;
block_List.remove(i + 1);
}
//若与之相邻上下分区都空闲
else if (block_List.get(i - 1).id == -1 && block_List.get(i + 1).id == -1) {
/*更新上一分区的size并删除本、下一分区*/
block_List.get(i - 1).size += blockSize;
block_List.get(i - 1).size += block_List.get(i + 1).size;
block_List.remove(i);
block_List.remove(i);
}
}
/*当分区为最后一个分区时*/
else if(i == blockList.size() - 1){
//若与之相邻上一个分区空闲
if (blockList.get(i - 1).id == -1) {
/*更新上一分区的size并删除本分区*/
blockList.get(i - 1).size += blockList.get(i).size;
blockList.remove(i);
}
}
flag = true;
break;
}
}
return flag;
}
/**
* 打印内存分配情况
*/
private static void show(List<Block> blockList) {
int i = 0;
System.out.println(" 首地址 分区大小 作业id");
for(Block block: blockList)
System.out.println(" 分区" + ++i + ":" + block);
System.out.println();
}
/**
* 操作面板
*/
private static void operator(){
String choose = "";
int id = 0;
int size = 0;
while(true) {
System.out.println("1.为新作业分配内存 2.作业完成释放内存");
System.out.println("3.查看当前内存分配 4.退出程序");
System.out.println("请输入待进行操作编号:");
choose = sc.next();
switch (choose) {
case "1":
System.out.println("作业id及申请空间大小:");
id = sc.nextInt();
size = sc.nextInt();
if (allocation(id, size))
System.out.println("内存分配成功。\n");
else
System.out.println("内存分配失败。\n");
break;
case "2":
System.out.println("待释放内存进程id:");
id = sc.nextInt();
if (release(blockList,id))
System.out.println("内存释放成功。\n");
else
System.out.println("内存释放失败。\n");
break;
case "3":
show(blockList);
break;
case "4":
System.exit(0);
}
}
}
/**
* main()
*/
public static void main(String[] args) {
initBlock();
operator();
}
}