超硬核!學霸把操作系統經典算法給敲完了!要知行合一

上期的筆記,瀏覽快1萬了,既然關注的人很多,那就發出來承諾過的算法全模擬,希望幫到你們。

上期的操作系統學霸筆記,考試復習面試全靠它

一、模擬進程調度

功能

data.h

#ifndef _Data_h_
#define _Data_h_#include <stdio.h>
#include <stdlib.h>
#include <string.h>#define ElemType PCB
#define Status int
#define OK		1
#define	ERROR	0
#define TimeSlice	1
#define Infinity 10 //INT_MAX#define NAME_MAXSIZE 20
typedef enum 
{Ready,Running,Block
}ProState;typedef enum 
{FCFS, SPF		//先來先服務,短進程優先
}PriorityRule;typedef struct 
{char Name[NAME_MAXSIZE];	//進程名int Priority;				//優先數int ArrivalTime;			//到達時間		以時間片為單位int NeedRunningTime;		//運行時間		以時間片為單位int StartTime;				//開始執行時間int FinishTime;				//完成時間int TimeUsedCPU;			//已用CPU時間		以時間片為單位ProState ProcessState;		//進程狀態
}PCB;typedef struct Node
{ElemType data;struct Node * Next;		
}LNode,*LinkList;#endif

?ChainList.h

#ifndef _ChainList_h_
#define _ChainList_h_#include "Data.h"//功能:鏈表初始化
Status Init(LinkList *L);//功能:賦值運算,將e2賦值給e1
void Assignment(ElemType *e1, ElemType e2);//功能:獲取第i個結點元素
Status GetElemt_L(LinkList L,int i,ElemType *e);//功能:鏈表根據優先級插入元素
Status ListInsert_L(LinkList L,ElemType e);//功能:鏈表刪除頭結點
Status ListDelete_L(LinkList L,ElemType *e);#endif

ProPCB.h

#ifndef _ProPCB_h_
#define _ProPCB_h_#include "ChainList.h"//功能:將e插入鏈表Q
Status GetProcess(LinkList Q,ElemType e);		//上就緒隊列//功能:根據不同的優先級規則,返回優先數
int GetPriority(ElemType *e, PriorityRule PR);  //根據不同的規則PR 設置優先數//功能:將鏈表Q的頭結點數據放到e指向的內存,并刪除
Status OutProsess(LinkList Q,ElemType *e);	    //下就緒隊列//功能:CPU運行pcb指向的進程,并輸出所有進行進程狀態
Status CPURunPro(LinkList Q, PCB *pcb);	        //CPU運行PCB//功能:打印所有PCB信息
void PrintProQueue(LinkList Q, PCB *pcb);		//打印運行后PCB信息//功能:當一個進程結束,打印進程信息
void PrintProResult(PCB *pcb);#endif

實現

#include "ChainList.h"extern int CPUUsedTime;//功能:鏈表初始化
Status Init(LinkList *L)
{*L = (LinkList)malloc(sizeof(LNode));(*L)->data.NeedRunningTime = -1;(*L)->Next = NULL;return OK;
}//功能:賦值運算,將e2賦值給e1
void Assignment(ElemType *e1, ElemType e2)
{e1->ArrivalTime = e2.ArrivalTime;strcpy(e1->Name,e2.Name);e1->Priority = e2.Priority;e1->ProcessState = e2.ProcessState;e1->FinishTime = e2.FinishTime;e1->StartTime = e2.StartTime;e1->NeedRunningTime = e2.NeedRunningTime;e1->TimeUsedCPU = e2.TimeUsedCPU;
}//鏈表中按照優先級:從大到小排序插入
Status ListInsert_L(LinkList L,ElemType e)	//這樣修改應該不對 p = *L出錯
{LinkList p = L->Next, pre = L, s;while (p && e.Priority <= p->data.Priority)	{pre = p;p = p->Next;}s = (LinkList)malloc(sizeof(LNode));Assignment(&s->data, e);s->Next = pre->Next;pre->Next = s;return OK;
}
//鏈表中頭部刪除
Status ListDelete_L(LinkList L,ElemType *e)
{LinkList p = L, q;q = p->Next;if(!q)return ERROR;p->Next = q->Next;Assignment(e, q->data);free(q);return OK;
}
#include "ProPCB.h"extern int CPUUsedTime;//功能:將e插入鏈表Q
Status GetProcess(LinkList Q,ElemType e)
{return ListInsert_L(Q, e);
}//功能:根據不同的優先級規則,返回優先數
int GetPriority(ElemType *e, PriorityRule PR)
{if(PR == FCFS)return Infinity - e->ArrivalTime;else if(PR == SPF)return Infinity - e->NeedRunningTime;elseprintf("GetPriority Function ERROR!\n");return ERROR;
}//功能:將鏈表Q的頭結點數據放到e指向的內存,并刪除
Status OutProsess(LinkList Q,ElemType *e)
{return ListDelete_L(Q ,e);
}//上一次CPU運行時間增加1個時間片
Status CPURunPro(LinkList Q,PCB *pcb)
{if(pcb->StartTime == -1)pcb->StartTime = CPUUsedTime;pcb->ProcessState = Running;//PrintProQueue(Q, pcb);pcb->TimeUsedCPU += TimeSlice;return OK;
}//功能:打印所有PCB信息
void PrintProQueue(LinkList Q, PCB *pcb)
{LinkList p = Q->Next;printf("進程名  優先數  到達時間  運行時間  已用CPU時間  完成時間  進程狀態\n");if(pcb)printf(" %4s     %2d      %4d      %4d     %3d(+1)       %3d        %4s  \n",pcb->Name,pcb->Priority,pcb->ArrivalTime,pcb->NeedRunningTime,pcb->TimeUsedCPU, pcb->FinishTime,pcb->ProcessState == Ready ? "就緒" : "運行");while (p){printf(" %4s     %2d      %4d      %4d     %3d           %3d        %4s  \n",p->data.Name,p->data.Priority,p->data.ArrivalTime,p->data.NeedRunningTime,p->data.TimeUsedCPU,p->data.FinishTime, p->data.ProcessState == Ready ? "就緒" : "運行");p = p->Next;}printf("-------------------------------------------------------------------------------\n");
}//功能:當一個進程結束,打印進程信息
void PrintProResult(PCB *pcb)
{printf("進程名  到達時刻 運行時間 開始時刻 完成時刻 周轉時間 帶權周轉時間 進程狀態\n");if(pcb)printf(" %2s     %3d      %4d        %4d      %3d     %4d       %5.2lf       %4s  \n",pcb->Name,pcb->ArrivalTime,pcb->NeedRunningTime,pcb->StartTime,pcb->FinishTime,pcb->FinishTime-pcb->ArrivalTime,((pcb->FinishTime - pcb->ArrivalTime)*1.0)/pcb->NeedRunningTime,"完成");printf("-------------------------------------------------------------------------------\n");
}

main:

#include "ProPCB.h"/****************************
*  實驗01: 非搶占式靜態優先權	*
*  ① 優先權始終保持不變		*
*  ② 一旦進入CPU便運行到結束	*
*  ③ FCFS只考慮到達時間進CPU	*
*  ④ SPF認為到達時間相同		*
****************************/int CPUUsedTime = 0;void InputData(LinkList * pPCBdata, PriorityRule PR)
{ElemType e = {{0},-1,-1,-1,-1,-1,0,Ready};e.ArrivalTime = 0;e.ProcessState = Ready;e.TimeUsedCPU = 0;strcpy(e.Name,"A");e.NeedRunningTime = 1;e.Priority = GetPriority(&e, PR);if(PR == SPF)   e.ArrivalTime = 0;GetProcess(*pPCBdata,e);e.ArrivalTime = 1;e.ProcessState = Ready;e.TimeUsedCPU = 0;strcpy(e.Name,"B");e.NeedRunningTime = 100;e.Priority = GetPriority(&e, PR);if(PR == SPF)   e.ArrivalTime = 0;GetProcess(*pPCBdata,e);e.ArrivalTime = 2;e.ProcessState = Ready;e.TimeUsedCPU = 0;strcpy(e.Name,"C");e.NeedRunningTime = 1;e.Priority = GetPriority(&e, PR);if(PR == SPF)   e.ArrivalTime = 0;GetProcess(*pPCBdata,e);e.ArrivalTime = 3;e.ProcessState = Ready;e.TimeUsedCPU = 0;strcpy(e.Name,"D");e.NeedRunningTime = 100;e.Priority = GetPriority(&e, PR);if(PR == SPF)   e.ArrivalTime = 0;GetProcess(*pPCBdata,e);}//void InputData1(LinkList * pPCBdata, PriorityRule PR)
//{
//    ElemType e = {{0},-1,-1,-1,-1,-1,0,Ready};
//    e.ArrivalTime = 0;
//    e.ProcessState = Ready;
//    e.TimeUsedCPU = 0;
//    strcpy(e.Name,"A");
//    e.NeedRunningTime = 4;
//    e.Priority = GetPriority(&e, PR);
//    if(PR == SPF)   e.ArrivalTime = 0;
//    GetProcess(*pPCBdata,e);
//
//    e.ArrivalTime = 1;
//    e.ProcessState = Ready;
//    e.TimeUsedCPU = 0;
//    strcpy(e.Name,"B");
//    e.NeedRunningTime = 3;
//    e.Priority = GetPriority(&e, PR);
//    if(PR == SPF)   e.ArrivalTime = 0;
//    GetProcess(*pPCBdata,e);
//
//    e.ArrivalTime = 2;
//    e.ProcessState = Ready;
//    e.TimeUsedCPU = 0;
//    strcpy(e.Name,"C");
//    e.NeedRunningTime = 5;
//    e.Priority = GetPriority(&e, PR);
//    if(PR == SPF)   e.ArrivalTime = 0;
//    GetProcess(*pPCBdata,e);
//
//    e.ArrivalTime = 3;
//    e.ProcessState = Ready;
//    e.TimeUsedCPU = 0;
//    strcpy(e.Name,"D");
//    e.NeedRunningTime = 2;
//    e.Priority = GetPriority(&e, PR);
//    if(PR == SPF)   e.ArrivalTime = 0;
//    GetProcess(*pPCBdata,e);
//
//    e.ArrivalTime = 4;
//    e.ProcessState = Ready;
//    e.TimeUsedCPU = 0;
//    strcpy(e.Name,"E");
//    e.NeedRunningTime = 4;
//    e.Priority = GetPriority(&e, PR);
//    if(PR == SPF)   e.ArrivalTime = 0;
//    GetProcess(*pPCBdata,e);
//}int main(void)
{LinkList PCBQueue;	//InitPCBdata里面存放PCB初始數據ElemType e = {{0},-1,-1,-1,-1,-1,0,Ready};ElemType *pcb = NULL;PriorityRule PR;PR = FCFS;	   //   SPF    or   FCFS//***********    初始化就緒隊列    *************//Init(&PCBQueue);InputData(&PCBQueue, PR);printf("初始數據如下:\n");PrintProQueue(PCBQueue, pcb);//***********    進程根據優先級上CPU    *************//printf("\n進程運行信息如下:\n");while (OutProsess(PCBQueue, &e)){//一次性運行完畢while(e.TimeUsedCPU < e.NeedRunningTime)	//上完CPU的進程是否完畢{CPURunPro(PCBQueue, &e);		        //上CPU++CPUUsedTime;					        //CPU時間增加}//***********    當進程執行完畢時打印輸出    *************//e.FinishTime = CPUUsedTime;PrintProResult(&e);}getchar();return 0;
}

二、模擬銀行家算法?

介紹

data.h

#ifndef _Data_h_
#define _Data_h_#include <stdio.h>
#include <stdlib.h>
#include <string.h>#define ElemType PCB
#define Status int
#define true				1
#define false				0
#define OK					1
#define	ERROR				0
#define RESOURCE_NUM		3
#define	MAX_RESOURCE_A_NUM	10
#define	MAX_RESOURCE_B_NUM	5
#define	MAX_RESOURCE_C_NUM	7
#define NAME_MAXSIZE		20
#define PCB_Num 5
typedef struct{int MaxNum[RESOURCE_NUM];			//需要每項資源個數int AllocationNum[RESOURCE_NUM];	//已占用每項資源個數int NeedNum[RESOURCE_NUM];			//還需要的每項資源個數
}ResourceList;typedef struct 
{char Name[NAME_MAXSIZE];			//進程名ResourceList resList;				//資源清單
}PCB;typedef struct Node
{ElemType data;struct Node * Next;		
}LNode,*LinkList;#endif

chainlist.h

#ifndef _ChainList_h_
#define _ChainList_h_#include "Data.h"Status Init(LinkList *L);
void Assignment(ElemType *e1, ElemType e2);
Status ListInsert_L(LinkList L,ElemType e);#endif

實現

ProPCB.h

#ifndef _ProPCB_h_
#define _ProPCB_h_#include "ChainList.h"
#include <string.h>
//上隊列
Status GetProcess(LinkList Q,ElemType e);		
//銀行家算法
Status BankerAlgorithm(int *Allocation, int *Request,int i, int *Need, int *Available);
//安全性檢測算法
Status SecurityCheck(int *Allocation,int *Need, int *Available);
//分配資源
Status AllocateResource(LinkList PCBdata , int pos , int *Request);
//獲取資源矩陣
void GetMatrixData(LinkList PCBdata,int *Max,int *Allocation,int *Need,int *Available);
//打印進程資源信息
void PrintProQueue(LinkList L, int *A);
//得到指定PCB名的位置
void GetPos(LinkList L, char *name, int len, int *pos);
//對當前的請求進行預分配
void PreGrant(int* Allocation, int *Request,int pos,int *Need, int *Available);
//正式分配算法
void GrantSource(LinkList L, int *Request, int pos, int *Available);#endif

chainlist.c

#include "ChainList.h"
extern int CPUUsedTime;
Status Init(LinkList *L)
{*L = (LinkList)malloc(sizeof(LNode));strcpy((*L)->data.Name, "");(*L)->Next = NULL;return OK;
}void Assignment(ElemType *e1, ElemType e2)
{int i = 0;strcpy(e1->Name,e2.Name);for(i = 0; i < RESOURCE_NUM; ++i){e1->resList.AllocationNum[i] = e2.resList.AllocationNum[i];e1->resList.MaxNum[i] = e2.resList.MaxNum[i];e1->resList.NeedNum[i] = e2.resList.NeedNum[i];}
}Status ListInsert_L(LinkList L,ElemType e)	//這樣修改應該不對 p = *L出錯
{LinkList p = L, s;while (p->Next)	p = p->Next;s = (LinkList)malloc(sizeof(LNode));Assignment(&s->data, e);s->Next = p->Next;p->Next = s;return OK;
}

ProPCB.c

#include "ProPCB.h"Status GetProcess(LinkList Q,ElemType e)
{return ListInsert_L(Q, e);
}Status AllocateResource(LinkList PCBdata , int pos , int *Request)
{int i = 1;LNode *p = PCBdata->Next;while (p && i < pos){p = p->Next;++i;}if(!p || i > pos)return ERROR;for (i = 0; i < RESOURCE_NUM; ++i){p->data.resList.AllocationNum[i] += Request[i];p->data.resList.NeedNum[i] -= Request[i];}return OK;
}
void GetMatrixData(LinkList PCBdata,int *Max,int *Allocation,int *Need,int *Available)
{LNode *p;int i, j, c = RESOURCE_NUM;Available[0] = Available[1] = Available[2] = 0;for(p = PCBdata->Next, i = 0; p; p = p->Next, ++i){for(j = 0; j < RESOURCE_NUM; ++j){Max[i * c + j] = p->data.resList.MaxNum[j];Allocation[i * c + j] = p->data.resList.AllocationNum[j];Need[i * c + j] = p->data.resList.NeedNum[j];}Available[0] += Allocation[i * c + 0];Available[1] += Allocation[i * c + 1];Available[2] += Allocation[i * c + 2];}Available[0] =  MAX_RESOURCE_A_NUM - Available[0];Available[1] =  MAX_RESOURCE_B_NUM - Available[1];Available[2] =  MAX_RESOURCE_C_NUM - Available[2];
}void PrintProQueue(LinkList L,int *available)
{int i = 0;L = L->Next;printf(" -------------------------------------------------------------\n");printf("|進程名 |     Max    |  Allocation |    Need    |  Available  |\n");printf("|       |  A   B   C |  A   B   C  | A   B   C  |  A   B   C  |\n");while(L){printf("|  %s   |  %d   %d   %d |  %d   %d   %d  | %d   %d   %d  |  %d   %d   %d  |\n",L->data.Name, L->data.resList.MaxNum[0], L->data.resList.MaxNum[1], L->data.resList.MaxNum[2],L->data.resList.AllocationNum[0],L->data.resList.AllocationNum[1],L->data.resList.AllocationNum[2],L->data.resList.NeedNum[0],L->data.resList.NeedNum[1],L->data.resList.NeedNum[2],available[0], available[1], available[2]);L = L->Next;}printf(" -------------------------------------------------------------\n");}//安全性檢測算法
Status SecurityCheck(int *Allocation,int *Need, int *Available)
{/ 以下補充  //int work[RESOURCE_NUM];int Finish[PCB_Num];int k, i, j, t, f;int flag;//初始化工作向量和標記數組memcpy(work, Available, sizeof work);memset(Finish, 0, sizeof Finish);//最多檢測PCB_Num次for(k = 0; k < PCB_Num; ++k){flag = 0;for(i = 0; i < PCB_Num; ++i){//已經被訪問if(Finish[i]){continue;}//檢測是否所有資源都能被分配for(j = 0; j < RESOURCE_NUM; ++j){if(!(Need[i * 3 + j] <= work[j])){break;}}//可以滿足,回收if(j == RESOURCE_NUM){for(t = 0; t < RESOURCE_NUM; ++t){work[t] += Allocation[i * 3 + t];}Finish[i] = 1;flag = 1;break;}}//為進行分配,跳出循環if(!flag){break;}}for(f = 0; f < PCB_Num; ++f){//只要有一個進程不滿足,跳出循環if(!Finish[f]){return ERROR;}}return OK;
}//銀行家算法
Status BankerAlgorithm(int* Allocation, int *Request,int pos,int *Need, int *Available)
{/ 以下補充  //int i;//檢查請求的是否大于需要的for(i = 0; i < RESOURCE_NUM; ++i){if(Request[i] > Need[pos*3 + i]){return ERROR;}}//檢查請求的是否大于可分配的for(i = 0; i < RESOURCE_NUM; ++i){if(Request[i] > Available[i]){return ERROR;}}//進行預分配PreGrant(Allocation, Request, pos, Need, Available);//進行安全性檢測if(!SecurityCheck(Allocation, Need, Available)){return ERROR;}return OK;
}//根據PCB的名字得到該PCB在鏈表中的位置
void GetPos(LinkList L, char *name, int len, int *pos)
{LinkList p = L->Next;char PcbName[NAME_MAXSIZE];memcpy(PcbName, name, (len + 1) * sizeof(char));(*pos) = 0;while(p){if(strcmp(p->data.Name, PcbName)){(*pos)++;p = p->Next;} else {break;}}
}//預分配算法
void PreGrant(int* Allocation, int *Request,int pos,int *Need, int *Available){int i;//1. Need減去請求的for(i = 0; i < RESOURCE_NUM; ++i){Need[pos*3 + i] -= Request[i];}//2. Available減去請求的for(i = 0; i < RESOURCE_NUM; ++i){Available[i] -= Request[i];}//3. Allocation加上請求的for(i = 0; i < RESOURCE_NUM; ++i){Allocation[pos*3 + i] += Request[i];}
}/*** 1.首先對請求資源的進程進行分配資源* 2.如果給該進程分配資源之后,該進程所需的資源等于已經得到的資源,那么對其擁有的資源進行回收*///正式分配算法,pos從0開始標記
void GrantSource(LinkList L, int *Request, int pos, int *Available){LinkList p = L->Next;int tag = 0;int i;int flag = 0;if(tag < pos && NULL != p){p = p->Next;tag++;}if(p){//已獲得的加上請求的for(i = 0; i < RESOURCE_NUM; ++i){p->data.resList.AllocationNum[i] += Request[i];}//還需要的減去請求的for(i = 0; i < RESOURCE_NUM; ++i){p->data.resList.NeedNum[i] -= Request[i];}//可利用的減去請求的for(i = 0; i < RESOURCE_NUM; ++i){Available[i] -= Request[i];}//如果進行分配之后該進程最大所需資源數目等于已獲得的資源數目,則對資源進行回收flag = 0;for(i = 0; i < RESOURCE_NUM; ++i){if(p->data.resList.AllocationNum[i] != p->data.resList.MaxNum[i]){flag = 1;break;}}if(!flag){for(i = 0; i < RESOURCE_NUM; ++i){Available[i] += p->data.resList.AllocationNum[i];}}}
}

main

#include "ProPCB.h"void InputData(LinkList * pPCBdata)
{ElemType e = {{0},{{0},{0},{0}}};strcpy(e.Name,"P0");e.resList.MaxNum[0] = 7;	e.resList.MaxNum[1] = 5;	e.resList.MaxNum[2] = 3;e.resList.AllocationNum[0] = 0;e.resList.AllocationNum[1] = 1;e.resList.AllocationNum[2] = 0;e.resList.NeedNum[0] = 7;	e.resList.NeedNum[1] = 4;	e.resList.NeedNum[2] = 3;	GetProcess(*pPCBdata,e);strcpy(e.Name,"P1");e.resList.MaxNum[0] = 3;	e.resList.MaxNum[1] = 2;	e.resList.MaxNum[2] = 2;e.resList.AllocationNum[0] = 2;e.resList.AllocationNum[1] = 0;e.resList.AllocationNum[2] = 0;e.resList.NeedNum[0] = 1;	e.resList.NeedNum[1] = 2;	e.resList.NeedNum[2] = 2;	GetProcess(*pPCBdata,e);strcpy(e.Name,"P2");e.resList.MaxNum[0] = 9;	e.resList.MaxNum[1] = 0;	e.resList.MaxNum[2] = 2;e.resList.AllocationNum[0] = 3;e.resList.AllocationNum[1] = 0;e.resList.AllocationNum[2] = 2;e.resList.NeedNum[0] = 6;	e.resList.NeedNum[1] = 0;	e.resList.NeedNum[2] = 0;	GetProcess(*pPCBdata,e);strcpy(e.Name,"P3");e.resList.MaxNum[0] = 2;	e.resList.MaxNum[1] = 2;	e.resList.MaxNum[2] = 2;e.resList.AllocationNum[0] = 2;e.resList.AllocationNum[1] = 1;e.resList.AllocationNum[2] = 1;e.resList.NeedNum[0] = 0;	e.resList.NeedNum[1] = 1;	e.resList.NeedNum[2] = 1;	GetProcess(*pPCBdata,e);strcpy(e.Name,"P4");e.resList.MaxNum[0] = 4;	e.resList.MaxNum[1] = 3;	e.resList.MaxNum[2] = 3;e.resList.AllocationNum[0] = 0;e.resList.AllocationNum[1] = 0;e.resList.AllocationNum[2] = 2;e.resList.NeedNum[0] = 4;	e.resList.NeedNum[1] = 3;	e.resList.NeedNum[2] = 1;	GetProcess(*pPCBdata,e);
}
int main(void)
{LinkList PCBdata;	//PCBdata里面存放原始數據ElemType e = {{0},{{0},{0},{0}}};char PcbName[NAME_MAXSIZE], chioce;int Max[PCB_Num][RESOURCE_NUM] = {0}, Allocation[PCB_Num][RESOURCE_NUM] = {0};int Need[PCB_Num][RESOURCE_NUM] = {0}, Available[RESOURCE_NUM] = {0};int Request[RESOURCE_NUM] = {0}, pos = 0;LNode *p = NULL;int i;/ 以下補充  ////初始化就緒隊列Init(&PCBdata);//數據輸入InputData(&PCBdata);while(1){//獲取所有PCB中的資源信息GetMatrixData(PCBdata, *Max, *Allocation, *Need, Available);//打印當前系統的狀態PrintProQueue(PCBdata, Available);//接受請求printf("請輸入申請資源的進程名,資源A,資源B,資源C申請量(空格隔開):");scanf("%s", PcbName);for(i = 0; i < RESOURCE_NUM; ++i){scanf("%d", &Request[i]);}//獲取相應的PCB在鏈表中的位置GetPos(PCBdata, PcbName, strlen(PcbName), &pos);//跑銀行家算法,根據返回值的狀態判斷是否安全,//如果安全,進行正式分配,否則僅僅打印不安全信息if(BankerAlgorithm(*Allocation, Request, pos, *Need, Available)){//正式分配資源GrantSource(PCBdata, Request, pos, Available);//分配完成后,打印資源的信息GetMatrixData(PCBdata, *Max, *Allocation, *Need, Available);PrintProQueue(PCBdata, Available);printf("請安任意鍵繼續. . . ");getchar();getchar();} else {printf("不安全,不可分配!\n");}}return 0;
}

三、模擬固定分區分配?

介紹

data.h

#ifndef _Data_h_
#define _Data_h_#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define LIST_INIT_SIZE 10
#define LISTINCREMENT  2
#define true				1
#define false				0
#define PCBType				PCB
#define Status				int
#define OK					1
#define	ERROR				0
#define NAME_MAXSIZE		20
#define PCB_Num				5
#define LIST_INITSIZE		10
#define PartiType			PartitionInfo
#define TotalMemory			512	//KBtypedef enum 
{Unallocated, Allocated
}DistributState, PartitionSt;typedef enum
{FirstPriority, BestAdapt
}AllocatStrategy;typedef struct 
{char Name[NAME_MAXSIZE];	//進程名int	MemorySize;				//內存的大小int StartAddress;			//內存起始地址DistributState DistbutSt;	//分配狀態
}PCB;typedef struct Node
{PCBType data;struct Node * Next;		
}LNode, *LinkList, *PCBList;			//typedef struct {//分區號用數組下標代替int PartitionSize;int PartStartAddr;char Name[NAME_MAXSIZE];//若為空,則分區空閑
}PartitionInfo;typedef struct
{PartiType *elem;int listsize;		//表容量int length;			//元素個數
}SqList, PartTable;		//分區表#endif 

list.h

#ifndef _List_h_
#define _List_h_#include "Data.h"//*******           鏈表            *******//
Status InitLinkList(LinkList *L);
void PCBAssign(PCBType *e1, PCBType e2);
Status GetElemt_L(LinkList L,int i,PCBType *e);
Status ListInsert_L(LinkList L,PCBType e);
Status ListDelete_L(LinkList L,int i,PCBType *e);//******         動態順序表           ******//
void PartiAssign(PartiType *e1, PartiType e2);
Status InitList_Sq(SqList *L);
Status ListInsert_Sq(SqList *L,int i,PartiType e);
Status ListDelete_Sq(SqList *L,int i,PartiType *e);#endif

?

#ifndef _MemoryManage_h_
#define _MemoryManage_h_#include "List.h"//*****         PCB鏈表操作        *****//
Status InsertProcess(LinkList Q,PCBType e);
Status DeleteProsess(LinkList Q,int i,PCBType *e);
//*****         分區表操作        *****//
Status InsertTable(SqList *L, int i, PartiType e);
Status DeleteTable(SqList *L, int i, PartiType *e);
int SelectPart(PCB* pPCB, SqList *pPartTable);
int MallocMemory(PCB *pe, SqList *pPartTable, int pos);
void SearchSpace(PCBList PCBdata, SqList partTable);
void FreeMemory(int pos, SqList *pPartTable);
void InitAllocation(PCBList PCBdata, PartTable partTable);
void PrintProQueue(LinkList L);
void PrintPartTable(PartTable L);#endif

實現

list.c

#include "List.h"Status InitLinkList(LinkList *L)
{*L = (LinkList)malloc(sizeof(LNode));strcpy((*L)->data.Name, "");(*L)->Next = NULL;return OK;
}void PCBAssign(PCBType *e1, PCBType e2)
{strcpy(e1->Name,e2.Name);e1->DistbutSt = e2.DistbutSt;e1->MemorySize = e2.MemorySize;e1->StartAddress = e2.StartAddress;
}Status GetElemt_L(LinkList L,int i,PCBType *e)
{LinkList p = L->Next;	//指向第j個結點int j = 1;				//從第一個開始往后找while ( p && j < i )	//p不為空且j < i{p = p->Next;++j;}						//p為空,說明鏈表循環結束,也沒有到第i個結點   j==iif (!p || j > i)		//因為此處對i   沒有做判斷   如果 i==0  或 負數  條件成立//對于 i == j == 1 的情況則不用循環正好  返回{return ERROR;}*e = p->data;			//通過尋址改變了 該地址內存中元素的值return OK;
}
//鏈表中按照優先級:從大到小排序插入
Status ListInsert_L(LinkList L,PCBType e)	//這樣修改應該不對 p = *L出錯
{LinkList p = L, s;while (p->Next)	p = p->Next;s = (LinkList)malloc(sizeof(LNode));PCBAssign(&s->data, e);s->Next = p->Next;p->Next = s;return OK;
}
//鏈表中頭部刪除
Status ListDelete_L(LinkList L,int i,PCBType *e)
{LinkList p = L, q;int j = 0;while (p->Next && j < i-1){p = p->Next; ++j;}if(!p->Next || j > i - 1)return ERROR;q = p->Next;p->Next = q->Next;PCBAssign(e, q->data);free(q);return OK;
}//           初始化         ///
void PartiAssign(PartiType *e1, PartiType e2)
{e1->PartitionSize = e2.PartitionSize;e1->PartStartAddr = e2.PartStartAddr;strcpy(e1->Name, e2.Name);
}Status InitList_Sq(SqList *L)
{//構造一個空的線性表LL->elem = (PartiType *)malloc((LIST_INIT_SIZE)*sizeof(PartiType));if(!L->elem) return ERROR;        //存儲分配失敗L->length = 0;                 //空表長度為0L->listsize = LIST_INIT_SIZE;  //初始存儲的容量return OK;
}//在順序線性表L中第i個位置之前插入新的元素e
Status ListInsert_Sq(SqList *L,int i,PartiType e)
{//在順序線性表L中第i個位置之前插入新的元素e//i的合法值為1 <= i <= ListLength_Sq(L)+1PartiType *q, *p, *newbase;if(i < 1 || i > L->length + 1 ) return ERROR;     //i值不合法if(L->length >= L->listsize){               //當前存儲空間已滿,增加分配newbase = (PartiType *)realloc(L->elem,(L->listsize + LISTINCREMENT)*sizeof(PartiType));if(!newbase) return ERROR;				//存儲分配失敗L->elem = newbase;						//新基址L->listsize += LISTINCREMENT;			//增加存儲容量} q = &(L->elem[i - 1]);			         	//q為插入位置for(p = &(L->elem[L->length-1]);p >= q; --p)PartiAssign((p+1),*p); 					//插入位置及之后的元素右移PartiAssign(q ,e);							//插入eL->length++;return OK;
}//在順序線性表L中刪除第i個元素,并用e返回其值
Status ListDelete_Sq(SqList *L,int i,PartiType *e)
{//在順序線性表L中刪除第i個元素,并用e返回其值//i的合法值為1 <= i <= ListLength_Sq(L)PartiType *p,*q;if((i < 1) || (i > L->length))	return ERROR;							 //i值不合法p = &(L->elem[i-1]);						 //p為被刪除元素的位置PartiAssign(e, *p);							 //將被刪除元素的值賦給e (待定)q = L->elem + L->length-1;					 //移動到表尾元素的位置for (++p;p<=q;++p)PartiAssign((p-1), *p);					 //被刪除元素之后的元素左移L->length--;return OK;
}

memoryManage.c

#include "MemoryManage.h"//*****         PCB鏈表操作        *****//
Status InsertProcess(LinkList Q,PCBType e)
{return ListInsert_L(Q, e);
}Status DeleteProsess(LinkList Q,int i,PCBType *e)
{return ListDelete_L(Q ,i,e);
}//*****         分區表操作        *****//
Status InsertTable(SqList *L, int i, PartiType e) 
{return ListInsert_Sq(L,i, e);
}Status DeleteTable(SqList *L, int i, PartiType *e)
{return ListDelete_Sq(L, i, e);
}//返回第幾個內存塊,從1開始,若返回0,則代表錯誤
int SelectPart(PCB* pPCB, SqList *pPartTable)
{int i,Start;if(pPCB->MemorySize <= 16)Start = 0;else if(pPCB->MemorySize <= 32)Start = 1;else if(pPCB->MemorySize <= 64)Start = 2;else if(pPCB->MemorySize <= 128)Start = 3;else if(pPCB->MemorySize <= 256)Start = 4;else{printf("內存過大,無法裝入!\n");return ERROR;}for (i = Start; i < pPartTable->length; ++i)if(!strcmp(pPartTable->elem[i].Name, ""))return i + 1;return ERROR;
}//i傳遞的是下標
int MallocMemory(PCB *pe, SqList *pPartTable,int i)
{///   以下需要補充    /pe->DistbutSt = Allocated;pe->StartAddress = pPartTable->elem[i].PartStartAddr;strcpy(pPartTable->elem[i].Name, pe->Name);return OK;
}/*** PCBdata:表示PCB鏈* partTable:分區表* 將每一個PCB取出,查找是否有合適的分區可以分配給他,如果有分配,如果沒有不分配*/ 
void InitAllocation(PCBList PCBdata, PartTable partTable)
{///   以下需要補充    /PCBList L = PCBdata->Next;int pos;while(L){pos = SelectPart(&L->data, &partTable);if(pos == 0) {printf("無法為%s進程分配空間!!!\n", L->data.Name);} else {L->data.DistbutSt = Allocated;L->data.StartAddress = partTable.elem[pos-1].PartStartAddr;strcpy(partTable.elem[pos-1].Name, L->data.Name);}L = L->Next;}//SearchSpace(PCBdata, partTable);
}void FreeMemory(int pos, SqList *pPartTable)
{///   以下需要補充    /strcpy(pPartTable->elem[pos].Name, "");
}void SearchSpace(PCBList PCBdata, SqList partTable)
{int pos;LNode *p;p = PCBdata->Next;while (p){if(p->data.DistbutSt == Unallocated){pos = SelectPart(&(p->data), &partTable);//從1開始if(pos){MallocMemory(&(p->data), &partTable, pos - 1);break;}}p = p->Next;}}void PrintProQueue(LinkList L)
{int i = 0;L = L->Next;printf(" ----------------------------------------\n");printf("|進程名 | 起始位置 | 申請大小 | 是否分配 |\n");while(L){printf("|  %s   |  %4d    |  %4d    |  %4s    |\n",L->data.Name, L->data.StartAddress, L->data.MemorySize, L->data.DistbutSt == Allocated?  "是" : "否");L = L->Next;}printf(" ----------------------------------------\n");
}void PrintPartTable(PartTable L)
{int i = 0, j = 0;printf(" ----------------------------------------\n");printf("|分區號 | 起始位置 | 分區大小 | 是否分配 |\n");for (i = 0; i < L.length; ++i)printf("|  %2d   |  %4d    |  %4d    |  %4s    |\n",i + 1 , L.elem[i].PartStartAddr, L.elem[i].PartitionSize , strcmp(L.elem[i].Name, "") ? L.elem[i].Name :"否");printf(" ----------------------------------------\n");
}

main

#include "MemoryManage.h"/*實驗06 固定分區分配
* 分配策略:
* ①離隊首最近,能夠裝入該分區的進程;
* ②搜索能夠裝入該分區最大的進程。
*/void InputPCBData(PCBList * pPCBdata)
{PCBType e = {{0}, 0, 0, Unallocated};strcpy(e.Name,"P1");e.MemorySize = 16;InsertProcess(*pPCBdata,e);strcpy(e.Name,"P2");e.MemorySize = 32;InsertProcess(*pPCBdata,e);strcpy(e.Name,"P3");e.MemorySize = 48;InsertProcess(*pPCBdata,e);strcpy(e.Name,"P4");e.MemorySize = 96;InsertProcess(*pPCBdata,e);strcpy(e.Name,"P5");e.MemorySize = 100;InsertProcess(*pPCBdata,e);
}void SetFixedZone(PartTable * pPartdata)
{PartiType se = {0, 0, Unallocated };se.PartStartAddr = 16;se.PartitionSize = 16;InsertTable(pPartdata, 1, se);se.PartStartAddr = 32;se.PartitionSize = 32;InsertTable(pPartdata, 2, se);se.PartStartAddr = 64;se.PartitionSize = 64;InsertTable(pPartdata, 3, se);se.PartStartAddr = 128;se.PartitionSize = 128;InsertTable(pPartdata, 4, se);se.PartStartAddr = 256;se.PartitionSize = 256;InsertTable(pPartdata, 5, se);}
//0 - 15Kb 操作系統占用  總大小512KB
int main(void)
{PCBList PCBdata;		//PCBdata里面存放原始PCB數據PartTable partTable;	//分區表char PcbName[NAME_MAXSIZE] = {0}, choice;PCBType PCBe = {{0}, 0, 0, Unallocated};PartiType Parte = {0, 0};PCBType tmp;PCBType *pcb = NULL;LNode *p; PCBList pl = NULL;int tpos = 0;int startAddress;int i, size, pos, j;InitList_Sq(&partTable);SetFixedZone(&partTable);InitLinkList(&PCBdata);InputPCBData(&PCBdata);InitAllocation(PCBdata, partTable);PrintProQueue(PCBdata);PrintPartTable(partTable);while(true){system("cls");PrintProQueue(PCBdata);PrintPartTable(partTable);printf(" ================================================\n");printf("|           1.結 束 進 程                        |\n");printf("|           2.添 加 進 程                        |\n");printf("|           3.退 出 系 統                        |\n");printf(" ================================================\n");printf("請選擇:");fflush(stdin);scanf("%d",&choice);//printf("haha");switch (choice){///   以下需要補充    /case 1:printf("要結束的進程名:");scanf("%s", PcbName);//找到指定進程的位置,pl = PCBdata->Next;startAddress = -1;tpos = 0;while(pl){tpos++;if(!strcmp(pl->data.Name, PcbName) && pl->data.DistbutSt == Allocated){startAddress = pl->data.StartAddress;break;}pl = pl->Next;}if(startAddress == -1){printf("進程不存在!!!\n");break;}//刪除進程DeleteProsess(PCBdata, tpos, &tmp);//根據起始地址找到要回收的分區for(j = 0; j < partTable.length; ++j){if(partTable.elem[j].PartStartAddr == startAddress){tpos = j;break;}}//回收內存FreeMemory(tpos, &partTable);//重新檢查是否可以為其他進程分配SearchSpace(PCBdata, partTable);break;case 2:printf("請輸入添加的進程名和所占分區的大小:");scanf("%s %d", PcbName, &size);strcpy(PCBe.Name, PcbName);PCBe.MemorySize = size;PCBe.DistbutSt = Unallocated;PCBe.StartAddress = 0;InsertProcess(PCBdata, PCBe);SearchSpace(PCBdata, partTable);break;case 3:exit(0);break;}PrintProQueue(PCBdata);PrintPartTable(partTable);system("pause");}return 0;
}

四、模擬基本分頁存儲

介紹

data.h

#ifndef _Data_h_
#define _Data_h_#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>#define LIST_INIT_SIZE 10
#define LISTINCREMENT  2
#define true				1
#define false				0
#define PCBType				PCB
#define Status				int
#define OK					1
#define	ERROR				0
#define NAME_MAXSIZE		20
#define PCB_Num				5
#define LIST_INITSIZE		10
#define PartiType			PartitionInfo
#define BlockNumType		PageData //分頁信息
#define TotalMemory			512	//KB
#define PageSize			16	//通常為1 ~ 8KB    //進程申請內存的大小[16, 256]KB    256 / 8 = 32頁typedef enum 
{Unallocated, Allocated
}DistributState, PartitionSt;typedef struct {//分區號用數組下標代替int PartStartAddr;char Name[NAME_MAXSIZE];//若為空,則分區空閑
}PartitionInfo;typedef struct
{PartitionInfo *elem;int listsize;		//表容量int length;			//元素個數
}SqList_f, PartTable;	//分區使用說明表typedef struct {					    int BlockNum;               //塊號DistributState DistbutSt;	//分配狀態
}PageData;typedef struct
{PageData *elem;	int listsize;		int length;			
}SqList_y, PageTable;	//頁表typedef struct 
{char Name[NAME_MAXSIZE];	//進程名int	MemorySize;				//內存的大小PageTable *pPagetable;		//頁表指針
}PCB;typedef struct Node
{PCBType data;struct Node * Next;		
}LNode, *LinkList, *PCBList;#endif 

list.h

#ifndef _List_h_
#define _List_h_#include "Data.h"//*******           鏈表            *******//
Status InitLinkList(LinkList *L);
void PCBAssign(PCBType *e1, PCBType e2);
Status GetElemt_L(LinkList L,int i,PCBType *e);
Status ListInsert_L(LinkList L,PCBType e);
Status ListDelete_L(LinkList L,int i,PCBType *e);//******         分區使用說明表           ******//
void PartiAssign_f(PartiType *e1, PartiType e2);
Status InitList_f(SqList_f *L);
Status ListInsert_f(SqList_f *L,int i,PartiType e);
Status ListDelete_f(SqList_f *L,int i,PartiType *e);//******         頁表           ******//
void PartiAssign_y(BlockNumType *e1, BlockNumType e2);
Status InitList_y(SqList_y **L);
Status ListInsert_y(SqList_y *L,int i,BlockNumType e);
Status ListDelete_y(SqList_y *L,int i,BlockNumType *e);#endif

memorymanage.h

#ifndef _MemoryManage_h_
#define _MemoryManage_h_#include "List.h"//*****         PCB 鏈 表 操 作        *****//
Status InsertProcess(LinkList Q,PCBType e);
Status DeleteProsess(LinkList Q,int i,PCBType *e);
//*****         分 區 表 操 作         *****//
//插入分區表元素
Status InsertTable_f(SqList_f *L, int i, PartiType e);	
//刪除分區表元素
Status DeleteTable_f(SqList_f *L, int i, PartiType *e);//******          頁 表 操 作         ******//
//插入頁表元素
Status InsertTable_y(SqList_y *L, int i, BlockNumType e);
//刪除頁表元素
Status DeleteTable_y(SqList_y *L, int i, BlockNumType *e);
Status LoadPages(PageTable *L, int size);Status MallocMemory(PCB *pe, SqList_f *pPartTable, int *arr);
Status SelectPart(PCB* pPCB, SqList_f *pPartTable,int *arr);
void SearchSpace(PCBList PCBdata, SqList_f *partTable);
void FreeMemory(int *arr, int len, SqList_f *pPartTable);
void InitAllocation(PCBList PCBdata, PartTable *partTable);
void PrintProQueue(LinkList L);
void PrintPartTable(PartTable L);#endif

實現

#include "List.h"//*******           鏈表            *******//
Status InitLinkList(LinkList *L)
{*L = (LinkList)malloc(sizeof(LNode));strcpy((*L)->data.Name, "");(*L)->Next = NULL;return OK;
}void PCBAssign(PCBType *e1, PCBType e2)
{strcpy(e1->Name,e2.Name);e1->MemorySize = e2.MemorySize;e1->pPagetable = e2.pPagetable;
}Status GetElemt_L(LinkList L,int i,PCBType *e)
{LinkList p = L->Next;	//指向第j個結點int j = 1;				//從第一個開始往后找while ( p && j < i )	//p不為空且j < i{p = p->Next;++j;}						//p為空,說明鏈表循環結束,也沒有到第i個結點   j==iif (!p || j > i)		//因為此處對i   沒有做判斷   如果 i==0  或 負數  條件成立//對于 i == j == 1 的情況則不用循環正好  返回{return ERROR;}*e = p->data;			//通過尋址改變了 該地址內存中元素的值return OK;
}
//鏈表中按照優先級:從大到小排序插入
Status ListInsert_L(LinkList L,PCBType e)	//這樣修改應該不對 p = *L出錯
{LinkList p = L, s;while (p->Next)	p = p->Next;s = (LinkList)malloc(sizeof(LNode));PCBAssign(&s->data, e);s->Next = p->Next;p->Next = s;return OK;
}Status ListDelete_L(LinkList L,int i,PCBType *e)
{LinkList p = L, q;int j = 0;while (p->Next && j < i-1){p = p->Next; ++j;}if(!p->Next || j > i - 1)return ERROR;q = p->Next;p->Next = q->Next;PCBAssign(e, q->data);free(q);return OK;
}//******         分區使用說明表           ******//
void PartiAssign_f(PartiType *e1, PartiType e2)
{e1->PartStartAddr = e2.PartStartAddr;strcpy(e1->Name, e2.Name);
}Status InitList_f(SqList_f *L)
{//構造一個空的線性表LL->elem = (PartiType *)malloc((LIST_INIT_SIZE)*sizeof(PartiType));if(!L->elem) return ERROR;        //存儲分配失敗L->length = 0;                 //空表長度為0L->listsize = LIST_INIT_SIZE;  //初始存儲的容量return OK;
}//在順序線性表L中第i個位置之前插入新的元素e
Status ListInsert_f(SqList_f *L,int i,PartiType e)
{//在順序線性表L中第i個位置之前插入新的元素e//i的合法值為1 <= i <= ListLength_Sq(L)+1PartiType *q, *p, *newbase;if(i < 1 || i > L->length + 1 ) return ERROR;     //i值不合法if(L->length >= L->listsize){               //當前存儲空間已滿,增加分配newbase = (PartiType *)realloc(L->elem,(L->listsize + LISTINCREMENT)*sizeof(PartiType));if(!newbase) return ERROR;				//存儲分配失敗L->elem = newbase;						//新基址L->listsize += LISTINCREMENT;			//增加存儲容量} q = &(L->elem[i - 1]);			         	//q為插入位置for(p = &(L->elem[L->length-1]);p >= q; --p)PartiAssign_f((p+1),*p); 					//插入位置及之后的元素右移PartiAssign_f(q ,e);							//插入eL->length++;return OK;
}//在順序線性表L中刪除第i個元素,并用e返回其值
Status ListDelete_f(SqList_f *L,int i,PartiType *e)
{//在順序線性表L中刪除第i個元素,并用e返回其值//i的合法值為1 <= i <= ListLength_Sq(L)PartiType *p,*q;if((i < 1) || (i > L->length))	return ERROR;							 //i值不合法p = &(L->elem[i-1]);						 //p為被刪除元素的位置PartiAssign_f(e, *p);							 //將被刪除元素的值賦給e (待定)q = L->elem + L->length-1;					 //移動到表尾元素的位置for (++p;p<=q;++p)PartiAssign_f((p-1), *p);					 //被刪除元素之后的元素左移L->length--;return OK;
}//******         頁表           ******//void PartiAssign_y(BlockNumType *e1, BlockNumType e2)
{(*e1).BlockNum = e2.BlockNum;(*e1).DistbutSt = e2.DistbutSt;
}Status InitList_y(SqList_y **L)
{//構造一個空的線性表L(*L) = (PageTable *)malloc(sizeof(PageTable));//不可缺少(*L)->elem = (BlockNumType *)malloc((LIST_INIT_SIZE)*sizeof(BlockNumType));if(!(*L)->elem) return ERROR;        //存儲分配失敗(*L)->length = 0;                 //空表長度為0(*L)->listsize = LIST_INIT_SIZE;  //初始存儲的容量return OK;
}//在順序線性表L中第i個位置之前插入新的元素e
Status ListInsert_y(SqList_y *L,int i,BlockNumType e)
{//在順序線性表L中第i個位置之前插入新的元素e//i的合法值為1 <= i <= ListLength_Sq(L)+1BlockNumType *q, *p, *newbase;if(i < 1 || i > L->length + 1 ) return ERROR;     //i值不合法if(L->length >= L->listsize){               //當前存儲空間已滿,增加分配newbase = (BlockNumType *)realloc(L->elem,(L->listsize + LISTINCREMENT)*sizeof(BlockNumType));if(!newbase) return ERROR;				//存儲分配失敗L->elem = newbase;						//新基址L->listsize += LISTINCREMENT;			//增加存儲容量} q = &(L->elem[i - 1]);			         	//q為插入位置for(p = &(L->elem[L->length-1]);p >= q; --p)PartiAssign_y((p+1),*p); 					//插入位置及之后的元素右移PartiAssign_y(q ,e);							//插入eL->length++;return OK;
}//在順序線性表L中刪除第i個元素,并用e返回其值
Status ListDelete_y(SqList_y *L,int i,BlockNumType *e)
{//在順序線性表L中刪除第i個元素,并用e返回其值//i的合法值為1 <= i <= ListLength_Sq(L)BlockNumType *p,*q;if((i < 1) || (i > L->length))	return ERROR;							 //i值不合法p = &(L->elem[i-1]);						 //p為被刪除元素的位置PartiAssign_y(e, *p);							 //將被刪除元素的值賦給e (待定)q = L->elem + L->length-1;					 //移動到表尾元素的位置for (++p;p<=q;++p)PartiAssign_y((p-1), *p);				 //被刪除元素之后的元素左移L->length--;return OK;
}

memorymanage.c


#include "MemoryManage.h"//*****         PCB鏈表操作        *****//
Status InsertProcess(LinkList Q,PCBType e)
{return ListInsert_L(Q, e);
}Status DeleteProsess(LinkList Q,int i,PCBType *e)
{return ListDelete_L(Q ,i,e);
}//*****         分區表操作        *****//
Status InsertTable_f(SqList_f *L, int i, PartiType e) 
{return ListInsert_f(L,i, e);
}Status DeleteTable_f(SqList_f *L, int i, PartiType *e)
{return ListDelete_f(L, i, e);
}//*****         頁表操作        *****//
Status InsertTable_y(SqList_y *L, int i, BlockNumType e)
{return ListInsert_y(L,i, e);
}Status DeleteTable_y(SqList_y *L, int i, BlockNumType *e)
{return ListDelete_y(L, i, e);
}Status LoadPages(PageTable *L, int size)
{int i, pageNum = ceil( size * 1.0 / PageSize) ;PageData e = {-1, Unallocated};for (i = 0; i < pageNum; i++){if(!InsertTable_y(L, L->length + 1, e))return ERROR;}return OK;;
}//若返回0,則代表錯誤
Status SelectPart(PCB* pPCB, SqList_f *pPartTable,int *arr)
{/     以下補充     /int i = 0, j = 0;while(i < pPCB->pPagetable->length && j < pPartTable->length){if(pPCB->pPagetable->elem[i].DistbutSt == Unallocated){if(!strcmp(pPartTable->elem[j].Name, "")){arr[i] = j;++i;++j;} else {++j;}} else {++i;}}if(i == pPCB->pPagetable->length){return OK;}return ERROR;
}Status MallocMemory(PCB *pe, SqList_f *pPartTable, int *arr)
{int i, pageNum ;以下補充     /for(i = 0; i < pe->pPagetable->length; ++i){if(pe->pPagetable->elem[i].DistbutSt == Unallocated){pe->pPagetable->elem[i].BlockNum = arr[i];pe->pPagetable->elem[i].DistbutSt = Allocated;strcpy(pPartTable->elem[arr[i]].Name, pe->Name);}}return ERROR;
}void InitAllocation(PCBList PCBdata, PartTable *pPartTable)
{LNode *p;int pos, arr[20] = {0};p = PCBdata->Next;while (p){if(p->data.pPagetable->elem[0].DistbutSt == Unallocated){if(SelectPart(&(p->data), pPartTable, arr)){MallocMemory(&(p->data), pPartTable, arr);}}p = p->Next;}
}//該釋放進程只在結束進程時用到,因此不用管進程信息
void FreeMemory(int *arr, int len, SqList_f *pPartTable)
{int i;以下補充   /for(i = 0; i < len; ++i){strcpy(pPartTable->elem[arr[i]].Name, "");}
}void SearchSpace(PCBList PCBdata, SqList_f *partTable)
{int pos, arr[20] = {0};LNode *p;p = PCBdata->Next;while (p){if(p->data.pPagetable->elem[0].DistbutSt == Unallocated){if(SelectPart(&(p->data), partTable, arr)){MallocMemory(&(p->data), partTable, arr);}}p = p->Next;}}void PrintProQueue(LinkList L)
{int i = 0;L = L->Next;while(L){printf(" -----------------------------\n");printf("|進程名 | 申請大小 |\n");printf("|  %s   |  %4d    |\n", L->data.Name, L->data.MemorySize);printf("%s頁表信息如下:\n|   頁號   |   塊號   | 是否分配 |\n", L->data.Name);for (i = 0; i < L->data.pPagetable->length; i++)printf("|  %4d    |  %4d    |  %4s    |\n", i , L->data.pPagetable->elem[i].BlockNum,L->data.pPagetable->elem[i].DistbutSt == Allocated?  "是" : "否");L = L->Next;}printf(" ----------------------------------------\n");
}void PrintPartTable(PartTable L)
{int i = 0, j = 0;printf(" ----------------------------------------\n");printf("|分區號 | 起始位置 | 分區大小 | 是否分配 |\n");for (i = 0; i < L.length; ++i)printf("|  %2d   |  %4d    |  %4d    |  %4s    |\n",i , L.elem[i].PartStartAddr, PageSize , strcmp(L.elem[i].Name, "") ? L.elem[i].Name :"否");printf(" ----------------------------------------\n");
}

main

#include "MemoryManage.h"/*   實驗08  基本分頁   */void InputPCBData(PCBList * pPCBdata)
{PCBType e = {{0}, 0, NULL};strcpy(e.Name,"P1");e.MemorySize = 16;InitList_y(&(e.pPagetable));LoadPages(e.pPagetable, e.MemorySize);InsertProcess(*pPCBdata,e);strcpy(e.Name,"P2");e.MemorySize = 32;InitList_y(&(e.pPagetable));LoadPages(e.pPagetable, e.MemorySize);InsertProcess(*pPCBdata,e);strcpy(e.Name,"P3");e.MemorySize = 48;InitList_y(&(e.pPagetable));LoadPages(e.pPagetable, e.MemorySize);InsertProcess(*pPCBdata,e);strcpy(e.Name,"P4");e.MemorySize = 96;InitList_y(&(e.pPagetable));LoadPages(e.pPagetable, e.MemorySize);InsertProcess(*pPCBdata,e);strcpy(e.Name,"P5");e.MemorySize = 100;InitList_y(&(e.pPagetable));LoadPages(e.pPagetable, e.MemorySize);InsertProcess(*pPCBdata,e);
}void SettingPage(PartTable * pPartdata)
{PartiType se = {0, {0}};int Num = (512 - 16) / PageSize , i;for (i = 0; i < Num; ++i){se.PartStartAddr = 16 + i * PageSize;InsertTable_f(pPartdata, i + 1, se);}
}
//0 - 15Kb 操作系統占用  總大小512KB
int main(void)
{PCBList PCBdata;		//PCBdata里面存放原始PCB數據PartTable partTable;	//分區表char PcbName[NAME_MAXSIZE] = {0}, choice;PCBType PCBe = {{0}, 0, NULL};PartiType Parte = {0, 0};PCBType *pcb = NULL;LNode *p; int i, size, pos, arr[20] = {0}, k = 0;InitList_f(&partTable);SettingPage(&partTable);InitLinkList(&PCBdata);InputPCBData(&PCBdata);InitAllocation(PCBdata, &partTable);PrintProQueue(PCBdata);PrintPartTable(partTable);while(true){system("cls");PrintProQueue(PCBdata);PrintPartTable(partTable);printf(" ================================================\n");printf("|           1.結 束 進 程                        |\n");printf("|           2.添 加 進 程                        |\n");printf("|           3.退 出 系 統                        |\n");printf(" ================================================\n");printf("請選擇:");fflush(stdin);scanf("%c",&choice);switch (choice){case '1':printf("要結束的進程名:");scanf("%s",PcbName);for (p = PCBdata->Next, i = 1; p && strcmp(PcbName, p->data.Name); i++, p = p->Next);if(!p){printf("進程名輸入錯誤!\n");break;}DeleteProsess(PCBdata, i, &PCBe);k = 0;for(i = 0; i < partTable.length; i++){if(!strcmp(PcbName, partTable.elem[i].Name)){arr[k++] = i;}}FreeMemory(arr, k, &partTable);SearchSpace(PCBdata, &partTable);break;case '2':printf("請輸入添加的進程名,進程所占內存大小:");scanf("%s%d",PcbName , &size);strcpy(PCBe.Name, PcbName);PCBe.MemorySize = size;InitList_y(&(PCBe.pPagetable));LoadPages(PCBe.pPagetable, PCBe.MemorySize);if(SelectPart(&(PCBe), &partTable, arr))MallocMemory(&(PCBe), &partTable, arr);InsertProcess(PCBdata, PCBe);break;case '3':return 0;default:printf("選擇項輸入錯誤,重新選擇!\n");break;}PrintProQueue(PCBdata);PrintPartTable(partTable);system("pause");}return 0;
}

?

五、模擬動態分區分配

介紹

list.h

#ifndef _List_h_
#define _List_h_#include "Data.h"//*******           鏈表            *******//
Status InitLinkList(LinkList *L);
void PCBAssign(PCBType *e1, PCBType e2);
Status GetElemt_L(LinkList L,int i,PCBType *e);
Status ListInsert_L(LinkList L,PCBType e);
Status ListDelete_L(LinkList L,int i,PCBType *e);//******         動態順序表           ******//
void PartiAssign(PartiType *e1, PartiType e2);
Status InitList_Sq(SqList *L);
Status ListInsert_Sq(SqList *L,int i,PartiType e);
Status ListDelete_Sq(SqList *L,int i,PartiType *e);#endif

MemoryManage.h

#ifndef _MemoryManage_h_
#define _MemoryManage_h_#include "List.h"//*****         PCB鏈表操作        *****//
Status InsertProcess(LinkList Q,PCBType e);
Status DeleteProsess(LinkList Q,int i,PCBType *e);
//*****         分區表操作        *****//
Status InsertTable(SqList *L, int i, PartiType e);
Status DeleteTable(SqList *L, int i, PartiType *e);
int SelectPart(PCB* pPCB, SqList *pPartTable, AllocatStrategy AS);
int MallocMemory(PCB *pe, SqList *pPartTable,int i);
void SearchSpace(PCBList PCBdata, SqList *partTable, AllocatStrategy AS);
void FreeMemory(int pos, SqList *pPartTable);
void InitAllocation(PCBList PCBdata, PartTable *partTable, AllocatStrategy AS);
void PrintProQueue(LinkList L);
void PrintPartTable(PartTable L);#endif

實現

list.c

#include "List.h"Status InitLinkList(LinkList *L)
{*L = (LinkList)malloc(sizeof(LNode));strcpy((*L)->data.Name, "");(*L)->Next = NULL;return OK;
}void PCBAssign(PCBType *e1, PCBType e2)
{strcpy(e1->Name,e2.Name);e1->DistbutSt = e2.DistbutSt;e1->MemorySize = e2.MemorySize;e1->StartAddress = e2.StartAddress;
}Status GetElemt_L(LinkList L,int i,PCBType *e)
{LinkList p = L->Next;	//指向第j個結點int j = 1;				//從第一個開始往后找while ( p && j < i )	//p不為空且j < i{p = p->Next;++j;}						//p為空,說明鏈表循環結束,也沒有到第i個結點   j==iif (!p || j > i)		//因為此處對i   沒有做判斷   如果 i==0  或 負數  條件成立//對于 i == j == 1 的情況則不用循環正好  返回{return ERROR;}*e = p->data;			//通過尋址改變了 該地址內存中元素的值return OK;
}
//鏈表中按照優先級:從大到小排序插入
Status ListInsert_L(LinkList L,PCBType e)	//這樣修改應該不對 p = *L出錯
{LinkList p = L, s;while (p->Next)	p = p->Next;s = (LinkList)malloc(sizeof(LNode));PCBAssign(&s->data, e);s->Next = p->Next;p->Next = s;return OK;
}
//鏈表中頭部刪除
Status ListDelete_L(LinkList L,int i,PCBType *e)
{LinkList p = L, q;int j = 0;while (p->Next && j < i-1){p = p->Next; ++j;}if(!p->Next || j > i - 1)return ERROR;q = p->Next;p->Next = q->Next;PCBAssign(e, q->data);free(q);return OK;
}//           初始化         ///
void PartiAssign(PartiType *e1, PartiType e2)
{e1->PartitionSize = e2.PartitionSize;e1->PartStartAddr = e2.PartStartAddr;strcpy(e1->Name, e2.Name);
}Status InitList_Sq(SqList *L)
{//構造一個空的線性表LL->elem = (PartiType *)malloc((LIST_INIT_SIZE)*sizeof(PartiType));if(!L->elem) return ERROR;        //存儲分配失敗L->length = 0;                 //空表長度為0L->listsize = LIST_INIT_SIZE;  //初始存儲的容量return OK;
}//在順序線性表L中第i個位置之前插入新的元素e
Status ListInsert_Sq(SqList *L,int i,PartiType e)
{//在順序線性表L中第i個位置之前插入新的元素e//i的合法值為1 <= i <= ListLength_Sq(L)+1PartiType *q, *p, *newbase;if(i < 1 || i > L->length + 1 ) return ERROR;     //i值不合法if(L->length >= L->listsize){               //當前存儲空間已滿,增加分配newbase = (PartiType *)realloc(L->elem,(L->listsize + LISTINCREMENT)*sizeof(PartiType));if(!newbase) return ERROR;				//存儲分配失敗L->elem = newbase;						//新基址L->listsize += LISTINCREMENT;			//增加存儲容量} q = &(L->elem[i - 1]);			         	//q為插入位置for(p = &(L->elem[L->length-1]);p >= q; --p)PartiAssign((p+1),*p); 					//插入位置及之后的元素右移PartiAssign(q ,e);							//插入eL->length++;return OK;
}//在順序線性表L中刪除第i個元素,并用e返回其值
Status ListDelete_Sq(SqList *L,int i,PartiType *e)
{//在順序線性表L中刪除第i個元素,并用e返回其值//i的合法值為1 <= i <= ListLength_Sq(L)PartiType *p,*q;if((i < 1) || (i > L->length))	return ERROR;							 //i值不合法p = &(L->elem[i-1]);						 //p為被刪除元素的位置PartiAssign(e, *p);							 //將被刪除元素的值賦給e (待定)q = L->elem + L->length-1;					 //移動到表尾元素的位置for (++p;p<=q;++p)PartiAssign((p-1), *p);					 //被刪除元素之后的元素左移L->length--;return OK;
}

?

#include "MemoryManage.h"
extern int CF_i;//*****         PCB鏈表操作        *****//
Status InsertProcess(LinkList Q,PCBType e)
{return ListInsert_L(Q, e);
}Status DeleteProsess(LinkList Q,int i,PCBType *e)
{return ListDelete_L(Q ,i,e);
}//*****         分區表操作        *****//
Status InsertTable(SqList *L, int i, PartiType e) 
{return ListInsert_Sq(L,i, e);
}Status DeleteTable(SqList *L, int i, PartiType *e)
{return ListDelete_Sq(L, i, e);
}//返回第幾個內存塊,從1開始,若返回0,則代表錯誤
int SelectPart(PCB* pPCB, SqList *pPartTable,AllocatStrategy AS)
{int i;int BestArr[20] = {0}, k = 0, min = 500, min_i = -1;if(AS == FirstPriority){for (i = 0; i < pPartTable->length; ++i)if(!strcmp(pPartTable->elem[i].Name, "") && pPartTable->elem[i].PartitionSize >= pPCB->MemorySize)return i + 1;}else if(AS == BestAdapt){以下補充   /for(i = 0; i < pPartTable->length; ++i){if(!strcmp(pPartTable->elem[i].Name, "") && pPartTable->elem[i].PartitionSize >= pPCB->MemorySize)if(pPartTable->elem[i].PartitionSize - pPCB->MemorySize < min){min = pPartTable->elem[i].PartitionSize - pPCB->MemorySize;min_i = i;}}return min_i+1;}else if(AS == CycleFirst){int flag = 0;以下補充   /for(i = CF_i; i < pPartTable->length; i = (i+1)%(pPartTable->length)){if(!strcmp(pPartTable->elem[i].Name, "") && pPartTable->elem[i].PartitionSize >= pPCB->MemorySize){CF_i = (i+1)%pPartTable->length;return i + 1;}if(flag && i == CF_i){break;}if(i == CF_i){flag = 1;}}return 0;}else{printf("算法選擇有誤!\n");}return ERROR;
}//通過SelectPart查找是否存在可以分配的分區,在main函數中進行調用本方法進行內存的分配
int MallocMemory(PCB *pe, SqList *pPartTable,int i)
{PartiType se = {0, 0, {0}};以下補充   ///修改PCBpe->DistbutSt = Allocated;pe->StartAddress = pPartTable->elem[i].PartStartAddr;if(pPartTable->elem[i].PartitionSize == pe->MemorySize){strcpy(pPartTable->elem[i].Name, pe->Name);} else {//修改分區使用說明表strcpy(pPartTable->elem[i].Name, "");pPartTable->elem[i].PartitionSize -= pe->MemorySize;pPartTable->elem[i].PartStartAddr += pe->MemorySize;//新建一個表目, 并插入分區表使用說明表strcpy(se.Name, pe->Name);se.PartitionSize = pe->MemorySize;se.PartStartAddr = pe->StartAddress;InsertTable(pPartTable, i+1, se);}return OK;
}void InitAllocation(PCBList PCBdata, PartTable *pPartTable,AllocatStrategy AS)
{LNode *p;int pos;p = PCBdata->Next;while (p){if(p->data.DistbutSt == Unallocated){pos = SelectPart(&(p->data), pPartTable, AS);//從1開始if(pos){MallocMemory( &(p->data), pPartTable, pos - 1);}}p = p->Next;}
}//回收指定位置的內存空間
void FreeMemory(int pos, SqList *pPartTable)//沒考慮  pos為0情況,沒考慮刪除后修改起始地址情況
{PartiType se = {0, 0, {0}};int flag = 0;以下補充   /if(pos != pPartTable->length-1){//為后一塊分配if(!strcmp(pPartTable->elem[pos+1].Name, "")){strcpy(pPartTable->elem[pos].Name, "");pPartTable->elem[pos].PartitionSize += pPartTable->elem[pos+1].PartitionSize;strcpy(se.Name, pPartTable->elem[pos+1].Name);se.PartitionSize = pPartTable->elem[pos+1].PartitionSize;se.PartStartAddr = pPartTable->elem[pos+1].PartStartAddr;DeleteTable(pPartTable, pos+1, &se);flag = 1;}}if(pos != 0){//為前一塊分配if(!strcmp(pPartTable->elem[pos-1].Name, "")){strcpy(pPartTable->elem[pos-1].Name, "");pPartTable->elem[pos-1].PartitionSize += pPartTable->elem[pos].PartitionSize;strcpy(se.Name, pPartTable->elem[pos-1].Name);se.PartitionSize = pPartTable->elem[pos-1].PartitionSize;se.PartStartAddr = pPartTable->elem[pos-1].PartStartAddr;DeleteTable(pPartTable, pos-1, &se);flag = 1;}}if(!flag){strcpy(pPartTable->elem[pos].Name, "");}
}void SearchSpace(PCBList PCBdata, SqList *partTable, AllocatStrategy AS)
{int pos;LNode *p;p = PCBdata->Next;while (p){if(p->data.DistbutSt == Unallocated){pos = SelectPart(&(p->data), partTable, AS);//從1開始if(pos){MallocMemory(&(p->data), partTable, pos - 1);}}p = p->Next;}}void PrintProQueue(LinkList L)
{int i = 0;L = L->Next;printf(" ----------------------------------------\n");printf("|進程名 | 起始位置 | 申請大小 | 是否分配 |\n");while(L){printf("|  %s   |  %4d    |  %4d    |  %4s    |\n",L->data.Name, L->data.StartAddress, L->data.MemorySize, L->data.DistbutSt == Allocated?  "是" : "否");L = L->Next;}printf(" ----------------------------------------\n");
}void PrintPartTable(PartTable L)
{int i = 0, j = 0;printf(" ----------------------------------------\n");printf("|分區號 | 起始位置 | 分區大小 | 是否分配 |\n");for (i = 0; i < L.length; ++i)printf("|  %2d   |  %4d    |  %4d    |  %4s    |\n",i + 1 , L.elem[i].PartStartAddr, L.elem[i].PartitionSize , strcmp(L.elem[i].Name, "") ? L.elem[i].Name :"否");printf(" ----------------------------------------\n");
}

main

#include "MemoryManage.h"/*實驗06 動態分區分配
*/int CF_i;void InputPCBData(PCBList * pPCBdata)
{PCBType e = {{0}, 0, 0, Unallocated};strcpy(e.Name,"P1");e.MemorySize = 16;InsertProcess(*pPCBdata,e);strcpy(e.Name,"P2");e.MemorySize = 32;InsertProcess(*pPCBdata,e);strcpy(e.Name,"P3");e.MemorySize = 48;InsertProcess(*pPCBdata,e);strcpy(e.Name,"P4");e.MemorySize = 96;InsertProcess(*pPCBdata,e);strcpy(e.Name,"P5");e.MemorySize = 100;InsertProcess(*pPCBdata,e);
}void SetFixedZone(PartTable * pPartdata)
{PartiType se = {0, 0, {0}};se.PartStartAddr = 16;se.PartitionSize = 512 - 16;strcpy(se.Name, "");InsertTable(pPartdata, 1, se);
}
//0 - 15Kb 操作系統占用  總大小512KB
int main(void)
{PCBList PCBdata;		//PCBdata里面存放原始PCB數據PartTable partTable;	//分區表char PcbName[NAME_MAXSIZE] = {0}, choice;PCBType PCBe = {{0}, 0, 0, Unallocated};PartiType Parte = {0, 0};PCBType *pcb = NULL;LNode *p; AllocatStrategy AS = CycleFirst; //FirstPriority, BestAdapt, CycleFirst//AllocatStrategy AS = BestAdapt;int i, size, pos;//分區表InitList_Sq(&partTable);SetFixedZone(&partTable);//進程表InitLinkList(&PCBdata);InputPCBData(&PCBdata);//初始化InitAllocation(PCBdata, &partTable, AS);CF_i = 0;PrintProQueue(PCBdata);PrintPartTable(partTable);while(true){system("cls");PrintProQueue(PCBdata);PrintPartTable(partTable);printf(" ================================================\n");printf("|           1.結 束 進 程                        |\n");printf("|           2.添 加 進 程                        |\n");printf("|           3.退 出 系 統                        |\n");printf(" ================================================\n");printf("請選擇:");fflush(stdin);scanf("%c",&choice);switch (choice){case '1':printf("要結束的進程名:");scanf("%s",PcbName);for (p = PCBdata->Next, i = 1; p && strcmp(PcbName, p->data.Name); i++, p = p->Next);if(!p){printf("進程名輸入錯誤!\n");break;}DeleteProsess(PCBdata, i, &PCBe);for(i = 0; i < partTable.length; i++){if(!strcmp(PcbName, partTable.elem[i].Name)){FreeMemory(i ,&partTable);break;}}SearchSpace( PCBdata, &partTable, AS);break;case '2':printf("請輸入添加的進程名,進程所占內存大小:");scanf("%s%d",PcbName , &size);PCBe.DistbutSt = Unallocated;PCBe.StartAddress = 0;strcpy(PCBe.Name, PcbName);PCBe.MemorySize = size;pos = SelectPart(&(PCBe), &partTable, AS);//從1開始if(pos)MallocMemory(&(PCBe), &partTable, pos - 1);InsertProcess(PCBdata, PCBe);break;case '3':return 0;default:printf("選擇項輸入錯誤,重新選擇!\n");break;}PrintProQueue(PCBdata);PrintPartTable(partTable);system("pause");}return 0;
}

?

?

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/443851.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/443851.shtml
英文地址,請注明出處:http://en.pswp.cn/news/443851.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

Python之數據轉換——【rename()方法、cut()函數、get_dummies()函數】

文章目錄重命名軸索引離散化連續數據啞變量處理類別型數據重命名軸索引 rename( self, mapper: Optional[Renamer] None, *, index: Optional[Renamer] None, columns: Optional[Renamer] None, axis: Optional[Axis] None, copy: bool True, inplace: bool False, level…

超硬核!數據結構學霸筆記,考試面試吹牛就靠它

上次發操作系統筆記&#xff0c;很快瀏覽上萬&#xff0c;這次數據結構比上次硬核的多哦&#xff0c;同樣的會發超硬核代碼&#xff0c;關注吧。 超硬核&#xff01;操作系統學霸筆記&#xff0c;考試復習面試全靠它 第一次筆記&#xff08;復習c&#xff0c;課程概述&#xff…

Python之數據拆分——groupby()方法

文章目錄groupby()方法通過列名進行分組通過Series對象進行分組Series對象與原數據的行索引長度相等Series對象與原數據的行索引長度不等通過字典進行分組按照columns軸的方向進行分組按照index軸的方向進行分組通過函數進行分組groupby()方法 groupby( self, byNone, axis0, l…

超硬核!小白讀了這篇文章,就能在算法圈混了

作為一只超級硬核的兔子&#xff0c;從來不給你說廢話&#xff0c;只有最有用的干貨&#xff01;這些神級算法送給你 目錄 第一節 1.1bogo排序 1.2位運算 1.3打擂臺 1.4morris遍歷 第二節 2.1睡眠排序 2.2會死的兔子 2.3矩陣快速冪 2.4摔手機/摔雞蛋 時空復雜度目錄 …

Python之數據聚合——aggregate()方法

文章目錄使用內置統計方法聚合數據面向列的聚合方法aggregate()方法對每一列數據應用同一個函數對某列數據應用不同的函數對不同列數據應用不同函數使用內置統計方法聚合數據 實現數據拆分成組并分別計算平均數的操作 代碼&#xff1a; import pandas as pd import numpy as…

超硬核十萬字!全網最全 數據結構 代碼,隨便秒殺老師/面試官,我說的

本文代碼實現基本按照《數據結構》課本目錄順序&#xff0c;外加大量的復雜算法實現&#xff0c;一篇文章足夠。能換你一個收藏了吧&#xff1f; 當然如果落下什么了歡迎大家評論指出 目錄 順序存儲線性表實現 單鏈表不帶頭標準c語言實現 單鏈表不帶頭壓縮c語言實現 約瑟…

Python之分組級運算——【transform()方法、apply()方法】

文章目錄數據轉換——transform()方法數據應用——apply()方法數據轉換——transform()方法 使用aggregate()方法進行聚合運算已經在上一篇博客中詳細闡述&#xff0c;我們知道aggregate()方法返回的數據集的形狀&#xff08;shape&#xff09;與被分組的數據集的形狀是不同的…

java限制在同一臺電腦上只允許有一個用戶登錄系統

在web應用系統中&#xff0c;出于安全性考慮&#xff0c;經常需要對同一客戶端登錄的用戶數量和一個客戶同時在多個客戶端登陸進行限制。 具體一點就是&#xff1a; 1、在同一臺電腦上一次只允許有一個用戶登錄系統&#xff1b; 2、一個用戶在同一時間只允許在一個客戶端登錄…

Matplotlib——繪制圖表

文章目錄通過figure()函數創建畫布通過subplot()函數創建單個子圖通過subplots()函數創建多個子圖通過add_subplot()方法添加和選中子圖添加各類標簽繪制常見圖表繪制直方圖——hist()函數繪制散點圖——scatter()函數繪制柱狀圖——bar()函數設定線條的相關參數本地保存圖片通…

限制在同一臺電腦上只允許有一個用戶登錄系統

在web應用系統中&#xff0c;出于安全性考慮&#xff0c;經常需要對同一客戶端登錄的用戶數量和一個客戶同時在多個客戶端登陸進行限制。 具體一點就是&#xff1a; 1、在同一臺電腦上一次只允許有一個用戶登錄系統&#xff1b; 2、一個用戶在同一時間只允許在一個客戶端登錄…

Seaborn——繪制統計圖形

文章目錄可視化數據的分布繪制單變量分布繪制雙變量分布繪制成對的雙變量分布用分類數據繪圖類別散點圖通過stripplot()函數畫散點圖swarmplot()函數類別內的數據分布繪制箱型圖繪制提琴圖類別內的統計估計繪制條形圖繪制點圖可視化數據的分布 繪制單變量分布 一般采用最簡單…

Bokeh——交互式可視化庫

文章目錄前言如何通過Plotting繪制圖形前言 Bokeh是一個專門針對Web瀏覽器使用的交互式可視化庫&#xff0c;這是與其他可視化庫相比最核心的區別。 如何通過Plotting繪制圖形 Plotting是以構建視覺符號為核心的接口&#xff0c;可以結合各種視覺元素&#xff08;例如&#x…

指針、引用以及const限定符、constexpr限定符

文章目錄復合類型引用概念與使用引用的定義注意指針概念聲明方式取地址符指針值空指針利用指針訪問對象賦值和指針void* 指針指向指針的指針指向指針的引用初始化所有指針有多重含義的某些符號const限定符概念const的引用指針和const頂層const和底層constconstexpr和常量表達式…

關鍵字typedef、關鍵字using、auto類型說明符和declytpe類型指示符

文章目錄類型別名概念關鍵字 typedef別名聲明 (alias declaration) using指針、常量和類型別名類型別名簡化多維數組指針auto類型說明符概念復合類型、常量和autodecltype類型指示符概念decltype和引用類型別名 概念 有兩種方法可用于定義類型別名。 關鍵字 typedef typede…

初始化、賦值、默認初始化、列表初始化、類內初始值、直接初始化與拷貝初始化

文章目錄初始化和賦值的區別什么是默認初始化&#xff1f;列表初始化列表初始化的使用場景不適合使用列表初始化的場景類內初始值混用string對象和C風格字符串數組與vector對象關于vector對象兩者間的初始化關系直接初始化與拷貝初始化初始化和賦值的區別 初始化的含義是創建變…

js動態增加,刪除td,tr,table,div

js實現的動態添加&#xff0c;刪除table內容&#xff1a; 截圖如下&#xff1a; 1. 2. 源代碼&#xff1a; main.css body {background-image: url(../images/qiantai/bg.png);font-family: arial;font-size: 12px;color: #d4d7da;text-align: center;background-repeat: r…

string類的相關知識及部分操作

文章目錄string對象的初始化string::size_type類型string對象的讀寫操作使用標準庫中的iostream使用getline讀取一整行string對象的比較操作string對象的相加操作兩個string對象相加字面值和string對象相加string對象的初始化 拷貝初始化(copy initialization)&#xff1a;使用…

數組的部分練習

3.27&#xff1a;假設txt_size是一個無參數的函數&#xff0c;它的返回值是int。請回答下列哪個定義是非法的&#xff1f;為什么&#xff1f; unsigned buf_size1024; &#xff08;a&#xff09;int ia[buf_size];  &#xff08;b&#xff09;int ia[4*7-14]; &#xff08…

關于范圍for語句的使用

文章目錄使用范圍for語句處理多維數組使用范圍for語句處理多維數組 舉個例子&#xff0c;使用范圍for語句輸出多維數組&#xff08;ia&#xff09;所有值&#xff1a; for (const auto &row : ia)for (auto col : row)cout << col << endl;本循環中并沒有任何…

vector的應用練習

文章目錄編寫一段程序&#xff0c;使用條件運算符從vector< int >中找出哪些元素的值是奇數&#xff0c;然后將奇數值翻倍。 #include <iostream> #include <ctime> #include <vector> using namespace std; typedef int int_array[4]; int main() {v…