❶ c#)图的深度优先搜索和广度优先搜索算法的实现
#include "exam8-2.cpp"
void BFS(ALGraph *G,int v)
{
ArcNode *p;
int queue[MAXV],front=0,rear=0; //定义循环队列并初始化
int visited[MAXV]; //定义存放结点的访问标志的数组
int w,i;
for (i=0;i<G->n;i++) visited[i]=0; //访问标志数组初始化
printf("%2d",v); //输出被访问顶点的编号
visited[v]=1; //置已访问标记
rear=(rear+1)%MAXV;
queue[rear]=v; //v进队
while (front!=rear) //若队列不空时循环
{ front=(front+1)%MAXV;
w=queue[front]; //出队并赋给w
p=G->adjlist[w].firstarc; //找与顶点w邻接的第一个顶点
while (p!=NULL)
{ if (visited[p->adjvex]==0) //若当前邻接顶点未被访问
{ printf("%2d",p->adjvex); //访问相邻顶点
visited[p->adjvex]=1; //置该顶点已被访问的标志
rear=(rear+1)%MAXV; //该顶点进队
queue[rear]=p->adjvex;
}
p=p->nextarc; //找下一个邻接顶点
}
}
printf("\n");
}
void main()
{
int i,j;
MGraph g;
ALGraph *G;
int A[MAXV][5]={
{0,1,0,1,1},
{1,0,1,1,0},
{0,1,0,1,1},
{1,1,1,0,1},
{1,0,1,1,0}};
g.n=5;g.e=16;
for (i=0;i<g.n;i++)
for (j=0;j<g.n;j++)
g.edges[i][j]=A[i][j];
G=(ALGraph *)malloc(sizeof(ALGraph));
MatToList(g,G);
printf(" 邻接表:\n");DispAdj(G);
printf("广度优先序列:");BFS(G,2);printf("\n");
}
以上为广度优先搜索遍历
#include "exam8-2.cpp"
int visited[MAXV];
void DFS(ALGraph *G,int v)
{
ArcNode *p;
visited[v]=1; //置已访问标记
printf("%d ",v); //输出被访问顶点的编号
p=G->adjlist[v].firstarc; //p指向顶点v的第一条弧的弧头结点
while (p!=NULL)
{
if (visited[p->adjvex]==0) //若p->adjvex顶点未访问,递归访问它
DFS(G,p->adjvex);
p=p->nextarc; //p指向顶点v的下一条弧的弧头结点
}
}
void main()
{
int i,j;
MGraph g;
ALGraph *G;
int A[MAXV][5]={
{0,1,0,1,1},
{1,0,1,1,0},
{0,1,0,1,1},
{1,1,1,0,1},
{1,0,1,1,0}};
g.n=5;g.e=16;
for (i=0;i<g.n;i++)
for (j=0;j<g.n;j++)
g.edges[i][j]=A[i][j];
G=(ALGraph *)malloc(sizeof(ALGraph));
MatToList(g,G);
printf(" 邻接表:\n");DispAdj(G);
for (i=0;i<MAXV;i++)
visited[i]=0;
printf("深度优先序列:");DFS(G,2);printf("\n");
}
这是深度优先搜索遍历。
具体还需自己懂后创新
❷ 优先级调度算法如何用JAVA实现
在多线程时,可以手动去设置每个线程的优先级setPriority(int newPriority)
更改线程的优先级。
❸ 求广度优先算法C++走迷宫程序,可以显示路径
一般迷宫寻路可以用递归的算法,或者用先进后出的栈数据结构实现
用的是深度优先的算法,可以寻找到走出迷宫的路径
但本题要求求出最短的路径,这就要使用广度优先的算法
一般在程序中需要用到先进先出的队列数据结构
下面是程序的代码,主要原理是用到
quei,quej和prep三个数组来构成队列
分别储存路径的行,列坐标和上一个节点在队列中的位置
大致算法如下,右三个嵌套的循环实现
首先是第一个节点进入队列
当队列不空(循环1)
{
遍历队列中每节点(循环2)
{
将八个方向能够走的节点加入队列(循环3)
}
旧的节点出列
}
#include<iostream>
#include<ctime>
usingnamespacestd;
#defineMAXNUM50
voidmain()
{
intm,n,i,j,x;
cout<<"请输入迷宫大小"<<endl;
cin>>m>>n;
intmaze[MAXNUM][MAXNUM];
srand((int)time(NULL));
for(i=0;i<=m+1;i++){
for(j=0;j<=n+1;j++){
if(i==0||j==0||i==m+1||j==n+1)
maze[i][j]=1;
else
{
x=rand()%1000;
if(x>700){maze[i][j]=1;}//控制矩阵中1的个数,太多1迷宫很容易走不通
else{maze[i][j]=0;}
}
cout<<maze[i][j]<<'';
}
cout<<endl;
}
//以上是输入和迷宫生成,一下是走迷宫
intmove[8][2]={0,1,1,0,0,-1,-1,0,1,1,-1,1,-1,-1,1,-1};
int*quei=newint[m*n];//储存行坐标队列
int*quej=newint[m*n];//储存列坐标队列
int*prep=newint[m*n];//储存之前一步在队列中的位置
inthead,rear,length;//队列头,队列尾,队列长度
head=0;rear=1;length=1;
quei[head]=1;quej[head]=1;prep[head]=-1;//入口位置进队列
intpos;//当前节点在队列中的位置,
intii,jj,ni,nj;//当前节点的坐标,新节点的坐标
intdir;//移动方向
if(maze[1][1]==1)length=0;//第一点就不能通过
elsemaze[1][1]=1;
while(length)//队列非空继续
{
for(pos=head;pos<head+length;pos++)//寻找这一层所有节点
{
ii=quei[pos];jj=quej[pos];//当前位置坐标
if(ii==m&&jj==n)break;
for(dir=0;dir<8;dir++)//寻找8个方向
{
ni=ii+move[dir][0];nj=jj+move[dir][1];//新坐标
if(maze[ni][nj]==0)//如果没有走过
{
quei[rear]=ni;quej[rear]=nj;prep[rear]=pos;//新节点入队
rear=rear+1;
maze[ni][nj]=1;//标记已经走过
}
}
}
if(ii==m&&jj==n)break;
head=head+length;
length=rear-head;//这一层节点出列
}
if(ii==m&&jj==n)
{
while(pos!=-1)
{
cout<<'('<<quei[pos]<<','<<quej[pos]<<')';
pos=prep[pos];
if(pos!=-1)cout<<',';
}
}
else
{
cout<<"THEREISNOPATH."<<endl;
}
delete[]quei;
delete[]quej;
delete[]prep;
}
❹ css优先级计算规则
梳理这部分是因为在使用组件模式开发h5应用会出现组件样式修改未生效的问题,在解决样式修改的问题前,需要理清楚CSS样式生效的优先级。样式根据引入和声明需要分开介绍,分为 引入样式优先级 和 声明样式优先级 。
引入样式优先级
引入样式优先级一般是在外部样式、内部样式、内联样式之间应用同一个样式的情况是使用, 优先级如下:
外部样式 | 内部样式 < 内联样式
外部样式 和 内部样式 ,最后出现的优先级最高,例如:
<!-- 内联样式 --><spanstyle="color:red;">Hello</span><styletype="text/css">/* 内部样式 */h3{color:green;}</style><!-- 外部样式 style.css --><linkrel="stylesheet"type="text/css"href="style.css"/>
因此,对于一些重置的样式集,比如 normalize.css/reset.css 必须写在所有样式的前面。
PS: 没有外联样式, 参考 。
声明样式优先级
1. 大致的优先级
一般来说满这个规则:
继承不如指定
!important > 内联 > ID > Class|属性|伪类 > 元素选择器
:link、:visited、:hover、:active按照LVHA(LoVe HAte)顺序定义
上面是优先级算法反映出的大致结果,在一般的开发中熟记即可。如果需要进一步研究原理,则了解下优先级算法。
2. 优先级算法
选择器的特殊性值分为四个等级,如下:
等级标签内选择符ID选择符Class选择符/属性选择符/伪类选择符元素选择符
示例<span style="color:red;">#text{color:red;}.text{color:red;} [type="text"]{color:red}span{color:red;}
标记位x,0,0,00,x,0,00,0,x,00,0,0,x
特点:
每个等级的初始值为0,
每个等级的叠加为选择器出 现的次数相加
不可进位,比如0,99,99,99
依次表示为:0,0,0,0
每个等级计数之间没关联
等级判断从左向右,如果某一位数值相同,则判断下一位数值
如果两个优先级相同,则最后出现的优先级高,!important也适用
通配符选择器的特殊性值为:0,0,0,0
继承样式优先级最低 ,通配符样式优先级高于继承样式
计算示例:
a{color: yellow;} /*特殊性值:0,0,0,1*/
div a{color: green;} /*特殊性值:0,0,0,2*/
.demo a{color: black;} /*特殊性值:0,0,1,1*/
.demo input[type="text"]{color: blue;} /*特殊性值:0,0,2,1*/
.demo *[type="text"]{color: grey;} /*特殊性值:0,0,2,0*/
#demo a{color: orange;} /*特殊性值:0,1,0,1*/
div#demo a{color: red;} /*特殊性值:0,1,0,2*/
生效示例:
<ahref="">第一条应该是黄色</a><!--适用第1行规则--><divclass="demo"><inputtype="text"value="第二条应该是蓝色"/><!--适用第4、5行规则,第4行优先级高--><ahref="">第三条应该是黑色</a><!--适用第2、3行规则,第3行优先级高--></div><divid="demo"><ahref="">第四条应该是红色</a><!--适用第6、7行规则,第7行优先级高--></div>
关于伪类LVHA的解释
a标签有四种状态:链接访问前、链接访问后、鼠标滑过、激活,分别对应四种伪类:link、:visited、:hover、:active;
当鼠标滑过a链接时,满足:link和:hover两个伪类,要改变a标签的颜色,就必须将:hover伪类在:link伪类后面声明;
当鼠标点击激活a链接时,同时满足:link、:hover、:active三种状态,要显示a标签激活时的样式(:active),必须将:active声明放到:link和:hover之后。因此得出LVHA这个顺序。
这个顺序能不能变?可以,但也只有:link和:visited可以交换位置,因为一个链接要么访问过要么没访问过,不可能同时满足,也就不存在覆盖的问题。
在组件中的应用
目前的前端开发为了增加开发效率,会对常用组件进行封装,此外,组件还会添加一些必要的结构样式。但是业务的设计文稿中可不一定按照预先写好的默认样式,需要在开发业务时根据组件的DOM结构修改默认样式,此时会出现样式不生效的问题。
例如下面的结构,如果对Title直接增加样式类,则肯定不会生效,因为Title的DOM结构为两层(组件样式定义规定不能使用ID选择器,且类选择器满足最小标记原则)),故样式最多为0,0,2,x。因此,样式多层标记就可提高自定义样式的优先级,例如下方的SCSS写法。
<Pageclass="test"><Headerclass="test__header"><Navbar><Titleclass="test__header--title">Toolbar</Title></Navbar></Header><Content></Content></Page>
.test{.test__header{.test__header--title{height:100px;}}}
此外,对于Page组件的样式标记策略推荐使用 金字塔形(树形) ,比如上面的SCSS书写,这样可以保证内部自定义样式不会受到外部干扰,减少不必要的麻烦。
链接:https://www.jianshu.com/p/1c4e639ff7d5
❺ 动态优先级调度算法
给你两个例子,第一个:http://dev.csdn.net/article/53/53415.shtm
第二个:
#include "stdio.h"
#include <STDLIB.H>
#include <CONIO.H>
#define getpch(type) (type*)malloc(sizeof(type))
#define NULL 0
struct pcb { /* 定义进程控制块PCB */
char name[10];
char state;
int super;
int ntime;
int rtime;
struct pcb* link;
}*ready=NULL,*p;
typedef struct pcb PCB;
sort() /* 建立对进程进行优先级排列函数*/
{
PCB *first, *second;
int insert=0;
if((ready==NULL)||((p->super)>(ready->super))) /*优先级最大者,插入队首*/
{
p->link=ready;
ready=p;
}
else /* 进程比较优先级,插入适当的位置中*/
{
first=ready;
second=first->link;
while(second!=NULL)
{
if((p->super)>(second->super)) /*若插入进程比当前进程优先数大,*/
{ /*插入到当前进程前面*/
p->link=second;
first->link=p;
second=NULL;
insert=1;
}
else /* 插入进程优先数最低,则插入到队尾*/
{
first=first->link;
second=second->link;
}
}
if(insert==0) first->link=p;
}
}
input() /* 建立进程控制块函数*/
{
int i,num;
//clrscr(); /*清屏*/
printf("\n 请输入进程号?");
scanf("%d",&num);
for(i=0;i<NUM;I++) scanf(?%s?,p- 输入进程名:?); printf(?\n p="getpch(PCB);" 进程号No.%d:\n?,i); {>name);
printf("\n 输入进程优先数:");
scanf("%d",&p->super);
printf("\n 输入进程运行时间:");
scanf("%d",&p->ntime);
printf("\n");
p->rtime=0;p->state='w';
p->link=NULL;
sort(); /* 调用sort函数*/
}
}
int space()
{
int l=0; PCB* pr=ready;
while(pr!=NULL)
{
l++;
pr=pr->link;
}
return(l);
}
disp(PCB * pr) /*建立进程显示函数,用于显示当前进程*/
{
printf("\n qname \t state \t super \t ndtime \t runtime \n");
printf("|%s\t",pr->name);
printf("|%c\t",pr->state);
printf("|%d\t",pr->super);
printf("|%d\t",pr->ntime);
printf("|%d\t",pr->rtime);
printf("\n");
}
check() /* 建立进程查看函数 */
{
PCB* pr;
printf("\n **** 当前正在运行的进程是:%s",p->name); /*显示当前运行进程*/
disp(p);
pr=ready;
printf("\n ****当前就绪队列状态为:\n"); /*显示就绪队列状态*/
while(pr!=NULL)
{
disp(pr);
pr=pr->link;
}
}
destroy() /*建立进程撤消函数(进程运行结束,撤消进程)*/
{
printf("\n 进程 [%s] 已完成.\n",p->name);
free(p);
}
running() /* 建立进程就绪函数(进程运行时间到,置就绪状态*/
{
(p->rtime)++;
if(p->rtime==p->ntime)
destroy(); /* 调用destroy函数*/
else
{
(p->super)--;
p->state='w';
sort(); /*调用sort函数*/
}
}
main() /*主函数*/
{
int len, h=0;
char ch;
input();
len=space();
while((len!=0)&&(ready!=NULL))
{
ch=getchar();
h++;
printf("\n The execute number:%d \n",h);
p=ready;
ready=p->link;
p->link=NULL;
p->state='R';
check();
running();
printf("\n 按任一键继续......");
ch=getchar();
}
printf("\n\n 进程已经完成.\n");
ch=getchar();
}
❻ 动态高优先权优先调度算法
动态高优先权优先调度算法:
动态优先权是指,在创建进程时所赋予的优先权,是可以随进程的推进或随其等待时间的增加而改变的,以便获得更好的调度性能。例如,我们可以规定,在就绪队列中的进程,随其等待时间的增长,其优先权以速率a提高。若所有的进程都具有相同的优先权初值,则显然是最先进入就绪队列的进程,将因其动态优先权变得最高而优先获得处理机,此即FCFS算法。若所有的就绪进程具有各不相同的优先权初值,那么,对于优先权初值低的进程,在等待了足够的时间后,其优先权便可能升为最高,从而可以获得处理机。当采用抢占式优先权调度算法时,如果再规定当前进程的优先权以速率b下降,则可防止一个长作业长期地垄断处理机。
算法代码模拟实现:
#include<stdio.h>
#include<stdlib.h>
#defineN6
//待插入就绪队列的进程数据
intid[N]={0,1,
2,3,4,
5};
intpriority[N]={9,38,17,
2,7,18};
intcpuTime[N]={0,
0,0,0,
0,0};
intallTime[N]={3,
2,3,6,
1,3};
//********************************
//
//模拟进程/PCB数据结构
//
//********************************
//
枚举进程的状态:就绪、执行、阻塞、完成
enumSTATE{Ready,Run,Block,Finish
};
//建立PCB结构体
structPCB{
intid;//标志数
intpriority;//优先数
intcpuTime;//
已占CPU时间
intallTime;//
还需占CPU时间
intblockTime;//已被阻塞的时间
STATEstate;//
进程状态
PCB*pre;//
PCB的前指针
PCB*nxt;//
PCB的后指针
};
//********************************
//
//模拟进程队列
//
//********************************
//进程入列
voidqueQush(PCB*process,PCB
*queHead)
{
process->pre=NULL;
process->nxt=
queHead->nxt;
if(queHead->nxt!=NULL){
//非第一个入列
queHead->nxt->pre=
process;
}
queHead->nxt=process;
}
//进程出列
voidquePop(PCB*process,PCB
*queHead)
{
if(process->pre!=NULL){
//不是头节点
process->pre->nxt=
process->nxt;
}
else{
queHead->nxt=
process->nxt;
}
if(process->nxt!=NULL){
//不是尾节点
process->nxt->pre=
process->pre;
}
//
清空进程指针
process->pre=process->nxt=
NULL;
}
//查看队列里进程的信息
voidqueWalk(PCB*queHead)
{
PCB*pro=queHead->nxt;
if(pro==NULL){
printf("(无进程) ");
return;
}
while(pro!=NULL)
{
printf("id:%d,
pri:%d,alltime:%d ",
pro->id,
pro->priority,
pro->allTime);
pro=
pro->nxt;
}
}
//********************************
//
//模拟就绪队列
//
//********************************
intreadyQueNum;//就绪队列的进程数量
PCBreadyQueHead;//
就绪队列的头部
PCB*readyMaxProcess;//就绪队列中优先级最高的进程
//进程插入到就绪队列
voidreadyQueQush(PCB
*process)
{
readyQueNum++;
process->state=Ready;
queQush(process,&readyQueHead);
}
//优先级最高的进程出列
PCB*readyQuePop()
{
readyQueNum--;
quePop(readyMaxProcess,
&readyQueHead);
returnreadyMaxProcess;
}
//每个时间片,更新就绪队列里进程的信息
voidreadyQueUpdate()
{
intmaxPriority=-1;
PCB*pro=readyQueHead.nxt;
if(pro==NULL){
//就绪队列没有进程
readyMaxProcess=
NULL;
return;
}
while(pro!=NULL)
{
pro->priority
++;
if(pro->priority>maxPriority)
{
maxPriority=
pro->priority;
readyMaxProcess=pro;
}
pro=
pro->nxt;
}
}
//返回就绪队列最高优先级的值
intreadyMaxPriority()
{
returnreadyMaxProcess->priority;
}
//查看就绪队列里进程的信息
voidreadyQueWalk()
{
printf("就绪队列里的进程信息为: ");
queWalk(&readyQueHead);
}
//********************************
//
//模拟阻塞队列
//
//********************************
#defineEndBlockTime3
//进程最长被阻塞时间
intblockQueNum;//阻塞队列的进程数量
PCBblockQueHead;//
阻塞队列的头部
PCB*blockMaxProcess;//阻塞队列中优先级最高的进程
//进程插入到阻塞队列
voidblockQueQush(PCB
*process)
{
blockQueNum++;
process->blockTime=0;
process->state=Block;
queQush(process,&blockQueHead);
}
//优先级最高的进程出列
PCB*blockQuePop()
{
blockQueNum--;
quePop(blockMaxProcess,
&blockQueHead);
returnblockMaxProcess;
}
//每个时间片,更新阻塞队列里进程的信息
voidblockQueUpdate()
{
intmaxPriority=-1;
PCB*pro=blockQueHead.nxt;
while(pro!=NULL)
{
pro->blockTime
++;
if(pro->blockTime>=EndBlockTime)
{
PCB*process=pro;
pro=pro->nxt;
//阻塞时间到,调入就绪队列
blockQueNum--;
quePop(process,
&blockQueHead);
readyQueQush(process);
}else
if(pro->priority>maxPriority)
{
//更新阻塞队列里优先级最高的进程指针
maxPriority=
pro->priority;
blockMaxProcess=pro;
pro=pro->nxt;
}
}
}
//查看阻塞队列里进程的信息
voidblockQueWalk()
{
printf("阻塞队列里的进程信息为: ");
queWalk(&blockQueHead);
}
//********************************
//
//模拟动态优先权的进程调度
//
//********************************
//初始化数据
voidinitData()
{
//
初始化就绪队列和阻塞队列
readyQueNum=blockQueNum=0;
readyMaxProcess=blockMaxProcess=NULL;
readyQueHead.pre=readyQueHead.nxt=NULL;
blockQueHead.pre=blockQueHead.nxt=NULL;
//
初始化进程进入就绪队列
inti,maxPriority=-1;
for(i=0;i<N;i
++)
{
//分配一个PCB的内存空间
PCB*pro=(PCB
*)malloc(sizeof(PCB));
//给当前的PCB赋值
pro->id
=id[i];
pro->priority
=priority[i];
pro->cpuTime
=cpuTime[i];
pro->allTime
=allTime[i];
pro->blockTime
=0;
if(pro->allTime>0){
//插入到就绪队列中
readyQueQush(pro);
//更新就绪队列优先级最高的进程指针
if(pro->priority>
maxPriority){
maxPriority=pro->priority;
readyMaxProcess=pro;
}
}
}
}
//模拟cpu执行1个时间片的操作
voidcpuWord(PCB
*cpuProcess)
{
cpuProcess->priority-=3;
if(cpuProcess->priority<0)
{
cpuProcess->priority=0;
}
cpuProcess->cpuTime++;
cpuProcess->allTime--;
//
显示正执行进程的信息:
printf("CPU正执行的进程信息为: ");
printf("id:M,pri:M,
alltime:M ",
cpuProcess->id,
cpuProcess->priority,
cpuProcess->allTime);
}
intmain()
{
inttimeSlice=0;//
模拟时间片
intcpuBusy=0;
//模拟cpu状态
PCB*cpuProcess=NULL;//当前在cpu执行的进程
//
初始化数据
initData();
//
模拟进程调度
while(1)
{
if(readyQueNum==0
&&blockQueNum==0
&&cpuBusy==0){
//就绪队列、阻塞队列和cpu无进程,退出
break;
}
//printf(" %d%d",
readyQueNum,blockQueNum);
if(cpuBusy==0)
{
//cpu空闲,选择一个进程进入cpu
if(readyQueNum>0)
{
//
选择绪队列优先级最高的进程
cpuProcess
=readyQuePop();
}else{
//
就绪队列没有进程,改为选择阻塞队列优先级最高的进程
cpuProcess
=blockQuePop();
}
cpuProcess->cpuTime=
0;
cpuProcess->state=
Run;
cpuBusy=1;
}
timeSlice++;
printf(" 第%d个时间片后: ",
timeSlice);
//
模拟cpu执行1个时间片的操作
cpuWord(cpuProcess);
if(cpuProcess->allTime==0){
cpuProcess->state=
Finish;
//释放已完成进程的PCB
free(cpuProcess);
cpuBusy=0;
}
//
更新就绪队列和阻塞队列里的进程信息
blockQueUpdate();
readyQueUpdate();
//
查看就绪队列和阻塞队列的进程信息
readyQueWalk();
blockQueWalk();
if(cpuBusy==1
&&readyQueNum>0
&&
cpuProcess->priority
<readyMaxPriority()){
//需抢占cpu,当前执行的进程调入阻塞队列
blockQueQush(cpuProcess);
cpuProcess=readyQuePop();
}
}
printf(" 模拟进程调度算法结束 ");
return0;
}