首页 > 代码库 > 【操作系统】Link.cpp
【操作系统】Link.cpp
/************************************************************************//* 功能: 模拟实现可变分区存储管理的最佳适应算法的链表类时间:2014年9月1日21:57:21作者:信管1201 1205020116 肖锋 *//************************************************************************/#include "Link.h"#include <iostream>using namespace std;//freeLink的定义实现//void swap(int index1, int index2); //交换连个节点的信息void freeLink::swap(int index1, int index2){ //交换这两个索引节点的所有信息 int i = 0; Node* p1 = head; while (i < index1) { p1 = p1->next; ++i; } int j = 0; Node* p2 = head; while (j < index2) { p2 = p2->next; ++j; } //p1和p2指向两个不同的节点,将要交换这两个节点,但是链表的位置不变 int size = p2->size; int adress = p2->adress; p2->size = p1->size; p2->adress = p1->adress; p1->size = size; p1->adress = adress;}//Node* getNode(int index);freeLink::Node* freeLink::getNode(int index){ int i = 0; Node* p=head; while (i < index) { p = p->next; ++i; } return p;}//给自由链表前后的合并分区,循环首次适应算法//void pingJie2();void freeLink::pingJie2(){ //首先把链表按照地址的大小排序 //冒泡排序 int count = 0; Node* p = head; while (p != tail) { p = p->next; ++count; } //冒泡排序,吧链表按地址递增的方式存放 for (int i = 1; i <= count; ++i) { for (int j = 1; j <= count - i; ++j) { Node *p1, *p2; p1 = getNode(j); p2 = getNode(j + 1); if (p1->adress > p2->adress) { swap(j, j + 1); } } } //排序完成之后考虑是否要合并 //考虑4种情况 Node *p1, *p2, *p3; if (count == 1) return; //只有一个空闲的节点还合并个屁啊 else if (count == 2) {//如果只有两个空闲的节点的话,那么就直接考虑向后合并 p1 = head->next; p2 = p1->next; if ((p1->adress + p1->size) == p2->adress) {//如果成立就直接合并这两个节点 p1->size += p2->size; //吧容量合并到p1上 delete p2; p1->next = nullptr; tail = p1; } } else //这就一般的情况,那就要考虑四种情况了 { p1 = head->next; p2 = p1->next; p3 = p2->next; //指向前三个,以p2为操作对象,进行判断 //一直判断到链表尾部 while (p3 != nullptr) { if ((p1->adress + p1->size) == p2->adress || (p2->adress + p2->size) == p3->adress) //要么前向,要么后巷,或者全要 { if ((p1->adress + p1->size) == p2->adress && (p2->adress + p2->size) != p3->adress) {//前向 //吧p2去除掉合并到p1里面去 p1->size += p2->size; //去除p2,不用考虑为节点 p1->next = p3; delete p2; p2 = p3; p3 = p2->next; } else if ((p1->adress + p1->size) != p2->adress && (p2->adress + p2->size) == p3->adress) {//向后合并 //吧p3去掉合并到p2里面去,这个要考虑尾部节点 p2->size += p3->size; if (p3 == tail) {//去除p3 tail = p2; delete p3; p3 == nullptr; } else { p2->next = p3->next; delete p3; p3 = p2->next; } } else if ((p1->adress + p1->size) == p2->adress && (p2->adress + p2->size) == p3->adress) {//前后一起合并,去除p2,p3,考虑尾部节点 p1->size += p2->size + p3->size; if (p3 == tail) { tail = p1; p1->next = nullptr; delete p2, p3; p3 = nullptr; } } else {//什么也不干的类型 //移动一位 p1 = p2; p2 = p3; p3 = p3->next; //整体下移一位 } } } }}//首次循环适应算法的添加,就是尾部添加//void addNode2(gSize, gAdress)void freeLink::addNode2(int size, int adress){ //直接尾部插入这个回收的节点 //这块内存的起始地址 Node* newNode = new Node(size, adress, 'O', nullptr); tail->next = newNode; tail = newNode; //添加到尾部}//循环首次适应//void setNeed(int index);void freeLink::setNeed(int index, int size){ Node* p; Node* p2; //就是要返回的索引对象 p = p2 = head->next; int i = 1; while (i < index) { p = p2; p2 = p2->next; ++i; } p2->size -= size; //把对应的空闲区间的大小修改 p2->adress += size; //新的起始地址 if (p2->size == 0) { if (p2 == tail) { //重置尾节点,并且去除大小为0的节点 delete p2; p->next = nullptr; tail = p; } else { //不是尾部节点,就直接去除大小为0的节点就可以了 p->next = p2->next; delete p2; } }}//删除尾部节点的函数//void popTail();void freeLink::popTail(){ //要去除尾部节点,就要重新给tail定位 Node* p; Node* p2; p = head; p2 = p->next; while (p2 != tail) { p = p2; p2 = p2->next; //循环直到指向最后一个 } //此时p2指向tail tail = p; delete p2; tail->next = nullptr;}//合并全部空闲的节点//void heBing();void freeLink::heBing(int allFreeAdress){ Node* p; Node* p2; p = head; p2 = p->next; int allFreeSize = 0; //统计所有的空闲区间的大小 //int allFreeAdress=0; //得到新的起始地址 while (head != tail) { allFreeSize += tail->size; popTail(); } //此时全部的节点都被删除,为空闲分区链添加一个最大的空间 addNode(allFreeSize, allFreeAdress);}//去除对应的节点//void popNeed(int index);void freeLink::popNeed(int index){ Node* p; Node* p2; //就是要返回的索引对象 p = p2 = head->next; int i = 1; while (i < index) { p = p2; p2 = p2->next; ++i; } //去除p2 p = p2->next; delete p2;}//得到index部节点的地址//int getNeedAdress(int index);int freeLink::getNeedAdress(int index){ Node* p; Node* p2; //就是要返回的索引对象 p = p2 = head->next; int i = 1; while (i < index) { p = p2; p2 = p2->next; ++i; } return p2->getAdress();}//得到第index位的size//int getNeedSize(int index);int freeLink::getNeedSize(int index){ Node* p; Node* p2; //就是要返回的索引对象 p = p2 = head->next; int i = 1; while (i < index) { p = p2; p2 = p2->next; ++i; } return p2->getSize();}//找到要修改的节点是第几位]//int getNeedGai(size);int freeLink::getNeedGai(int size){ int index = 1; //返回索引 Node* p; Node* p2; p = p2 = head->next; //p2指向要修改的节点 while (p2->size < size || p2 == nullptr) { p = p2; p2 = p2->next; ++index; } if (p2 == nullptr) return 0; return index; //返回当前位置的索引}//设置第i个节点//void setHeadNode(int index, int size, int adress);void freeLink::setNode(int index, int size, int adress){ Node* p; Node* p2; //p2指向要修改的节点 p = head; p2 = p->next; for (int i = 1; i < index; ++i) { p = p2; p2 = p2->next; //要修改的对象 } /* p2->size = size; p2->adress = adress; */ //吧原来的节点删除,重新插入到正确的位置 //Node* newPaiXu = new Node(size, adress, 'O', nullptr); if (p2 == tail) { //如果p2是尾节点,那就重置为节点,在插入 delete p2; p->next = nullptr; tail = p; } else { //不是尾部节点那就直接断 p->next = p2->next; delete p2; } //插入 addNode(size, adress);}//显示当前的分区//void show();void freeLink::show(){ Node* p; p = head->next; cout << "自由分区的链表是(剩余, 起始地址)" << endl; while (p != nullptr) { cout << "(" << p->size << " , " << p->adress << ")->"; p = p->next; } cout << endl;}//内存地址相同的时候的碎片拼接//void pingJie();//2014年9月2日17:03:46有问题void freeLink::pingJie(){ Node* p; Node* p2; p = head; //指向头结点 p2 = p->next; //指向第一个节点 //int count=1; int qiShiAdress; //这样来合并,用起始地址加内存的值在链表中找,是不是有节点的起始和他相同,如果相同就向后合并,遍历整个链表 while (p2 != nullptr) { qiShiAdress = p2->adress + p2->size; Node* p2_3 = head; for (Node* p3 = head->next; p3 != nullptr; p3 = p3->next) //p2_3指向p3的前面 { if (qiShiAdress == p3->adress) { //找到了可以合并的那么就直接把这两个节点合并,把找到的这两个去掉重新插入 int newAdress = p2->adress; int newSize = p2->size + p3->size; //这里断掉链表要小心不是紧挨着,断开怎么断? if (p2->next == p3) { p->next = p3->next; } else { p->next = p2->next; p2_3->next = p3->next; } delete p2, p3; p2 = p->next; //Node* chaRu=new Node(newSize, newAdress, 'O', nullptr); this->addNode(newSize, newAdress); qiShiAdress = 0; //重置,作为标准,以便后面判断是否还要到下一个节点 break; } p2_3 = p3; } if (qiShiAdress != 0) { p = p2; p2 = p2->next; } } /* //!2014年9月3日09:19:37 //这里考虑到保持的时候是从小到大,而拼接是按地址重后到前的排序的 //把Node按地址的位置重新排序保存的vector里面去 //先知道一共有多少个节点 while(p2 != nullptr) { p=p2; p2=p2->next; ++count; //当p指向尾节点,那就结束,统计一共有多少个节点 } //重置p,p2 p=head->next; p2=p->next; //直到全部按地址递增的方式全部放入到vector里面去 //然后按地址取出Node,按上面的方式合并 //找到可以拼接的地方进行拼接 //while(p2 != nullptr) //重头找到尾,找到就直接跳出,找不到就到达尾部 //{//可能有多处要合并不止一处 if((p->adress+p->size) == p2->adress) { //如果是末尾的话,要重置尾指针 if(p2 == tail) { tail=p; } //如果有可以合并的区间的话 //1、吧p的内存大小改变成p和p2的内存和 p->size+=p2->size; //2、吧p的指针指向p2的后面 p->next=p2->next; //3、吧p2断开,然后释放p2 delete p2; } p=p2; p2=p2->next; //} //如果是尾部节点的话,那么就是没有可以合并的区间 if(p == tail) {//看是不是只有一个节点 cout<<"xxx"<<endl; } else { while(p->next != tail || (p->adress+p->size) != p2->adress) //找到可以合并的区间,或者到了尾部节点 { //cout<<"xxx"<<endl; p=p2; //吧p和p2整体向前移动一位 p2=p2->next; } if((p->adress+p->size) == p2->adress && p->next == tail) { //如果有可以合并的区间的话 //1、吧p的内存大小改变成p和p2的内存和 p->size+=p2->size; //2、吧p的指针指向p2的后面 p->next=p2->next; //3、吧p2断开,然后释放p2 delete p2; tail=p; //重置尾节点 } } */}//添加一个Node,等会选择插入的地点//void addNode(int size, int adress);void freeLink::addNode(int size, int adress){ //1、先找到要插入的位置节点p指向前面的那个节点,p2指向后面那个节点 Node* p; Node* p2; p = head; p2 = head->next; if (p2 != nullptr) { while (p2->size < size) //找到比size要大的第一个节点 { p = p2; p2 = p2->next; if (p == tail) break; } } //判断是不是尾节点,不然要重置尾节点 if (p2 == nullptr) { //如果是尾部节点,那就直接加上去就可以了 Node* p3 = new Node(size, adress, 'O', nullptr); tail->next = p3; //重置尾节点 tail = p3; } else { //2、创建一个节点保存这个内存信息,这个节点插入到p和p2之间 //这块内存的起始地址 Node* newNode = new Node(size, adress, 'O', p2); //3、插入链表 //就是把newNode插入到两点之间 p->next = newNode; }}//删除Node//void popNode(char name);/*freeLink::Node* freeLink::popNode(char name){//空闲分区删除节点一般是改变节点的大小//判断是要改变还是要删除}*///busyLink类的定义//合并所有adress回收碎片//void reAdress();int busyLink::reAdress(){ Node* p; Node* p2; p = head; p2 = p->next; int endAdress = 0; //循环到队尾,size不变,adress全部重置 while (p != tail) { p2->adress = p->adress + p->size; //把这个节点的起始地址改为上个节点的结束 p = p2; p2 = p2->next; //指向下一个 } //当最后一个也得到处理的时候 //重定位结束, //后面再调用freeLink里面的函数,把所有的free节点收集起来做成一个大的空闲节点 endAdress = tail->adress + tail->size; return endAdress;}//得到索引节点的adress//int getNeedAdress(int index);int busyLink::getNeedAdress(int index){ Node* p; Node* p2; //就是要返回的索引对象 p = p2 = head->next; int i = 1; while (i < index) { p = p2; p2 = p2->next; ++i; } //cout<<"p2 name:"<<p2->name<<endl; return p2->adress; //记得加return 返回啊!!!!我的天浪费我半天}//得到索引节点的size//int getNeedSize(int index);int busyLink::getNeedSize(int index){ Node* p; Node* p2; //就是要返回的索引对象 p = p2 = head->next; int i = 1; while (i < index) { p = p2; p2 = p2->next; ++i; } p2->getSize(); return p2->getSize();}//得到需要的该的节点的索引//int getNeedGai(char name);int busyLink::getNeedGai(char name){ int index = 1; //返回索引 Node* p; Node* p2; p = p2 = head->next; //p2指向要修改的节点 while (p2->name != name) { p = p2; p2 = p2->next; ++index; if (p == tail) break; } if (p2 == nullptr) return 0; //cout<<index<<endl; return index; //返回当前位置的索引}//显示当前的分区//void show();void busyLink::show(){ Node* p; p = head->next; cout << "作业分区的链表是(剩余, 名字, 起始地址)" << endl; while (p != nullptr) { cout << "(" << p->size << " , " << p->name << " , " << p->adress << ")->"; p = p->next; } cout << endl;}//内存地址相同的时候的碎片拼接//void pingJie();//添加一个Node,等会选择插入的地点//void addNode(int size, int adress, char name);void busyLink::addNode(int size, int adress, char name){ //工作链表添加的作业直接添加到尾部就可以了 Node* p; //创建一个将要进入内存的作业 p = new Node(size, adress, name, nullptr); //其实这里析构函数应该回收p的内存 tail->next = p; tail = p;}//删除Node//void popNode(char name);void busyLink::popNode(char name){ Node* p; Node* p2; //1、找到名字为c的内存 p = p2 = head->next; while (p2->name != name || p2 == nullptr) { p = p2; p2 = p2->next; } if (p2 == nullptr) { std::cout << "不好意思,没有这个作业进入内存" << std::endl; return; } //2、得到这块内存里面的值 //int oldAdd=p2->adress; //int oldsize=p2->size; //3、创建一个节点保存这个内存的值 //Node* p3=new Node(oldsize, oldAdd, name, nullptr); //4、回收原来的这块内存 if (p->next == tail) { delete p2; p->next = nullptr; tail = p; } else { p->next = p2->next; delete p2; }}
【操作系统】Link.cpp
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。