图的应用的实验报告Word下载.docx
《图的应用的实验报告Word下载.docx》由会员分享,可在线阅读,更多相关《图的应用的实验报告Word下载.docx(13页珍藏版)》请在冰豆网上搜索。
intIsquan;
〃是否含有权值
}MGraph;
typedefstruct
int*top;
int*base;
intstacksize;
}Sqstack;
typedefintElemType;
StatusInitstack(Sqstack&
s)
s.base=(int*)malloc(sizeof(int)*25);
if(!
s.base)
returnERROR;
s.top=s.base;
s.stacksize=25;
returnOK;
}
intindegree[MAX_VERTEX_NUM];
intve[MAX_VERTEX_NUM];
//e各顶点的最早发生时间
intvl[MAX_VERTEX_NUM];
〃各顶点发生的最晚发生时间
调用的函数
StatusPop(Sqstack&
s,int&
e)
//若栈不空,则删除S的栈顶元素,
//用e返回其值,并返回OK否则返回ERROR
intPush(Sqstack&
intStackEmpty(Sqstacks)//若栈为空栈,则返回TRUE否则返回FLASE
StatusCreateGraph(MGraph&
G)
voidDisplay(MGraph&
G)/*输出图G的信息*/
voidFindDegree(MGraphg,intindegree[])//对=图中的各个顶点的入度进行统计,并
将第i
//个顶点的入度数放入indegree[i]
intLocateVex(MGraphG,VertexTypeu)
/*初始条件:
图G存在,u和G中顶点有相同特征*/
/*操作结果:
若G中存在顶点u,则返回该顶点在图中位置;
否则返回-1*/
StatusToopologicalSort(MGraphg)//对图进行拓扑排序,并输出拓扑排序的结果
StatusToopologicalOrder(MGraphg,Sqstack&
T)〃拓扑序列
StatusCriticalPath(MGraphg,SqstackT)//关键路径
㈡、函数调用及主函数设计(可用函数的调用关系图说明)
voidmain(){
MGraphg;
SqstackT;
cout«
"
创建图:
\n"
;
CreateGraph(g);
cout«
输出图的信息:
Display(g);
拓扑排序:
ToopologicalSort(g);
求关键历经:
ToopologicalOrder(g,T);
CriticalPath(g,T);
㈢程序调试及运行结果分析
(1)在创建图的过程中需要考虑输入的方便,这就需要标记根据用户选择是否需要输入权值,选择不需要权值时就不会有关权值信息的操作。
所以这就在图的结构体中加ISquan标记(0表示无权值,其他表示有权值)
(2)FindIndegree()函数调用过程就是一个对邻接表遍历的过程,在遍历
过程中需要将弧指向的结点进行入度数组的标记。
便定义了一个Indegree『』数
组。
(3)在求关键路径时,需要两次用到拓扑排序(其中一次是逆拓扑排序),在拓扑排序时还需要注意看看是否有环,若有环则输出提示信息。
㈣实验总结
通过对拓扑排序和求最小路径的操作,首先加强了对图的存储结构和图的遍历的进一步的熟悉和应用,在拓扑排序中还让我们去应用到以前学习的栈的知识,温故的同时也在实践的新的理论。
对图的应用是在生活中应用很广泛,同时图的知识点和算法也是我们这学期学习的精华,例如求关键路径,用到栈,拓扑排序等经典算法,让我们受益匪浅。
四、主要算法流程图及程序清单
1、主要算法流程图:
创建顶点向量的数组
创建了图的邻接表
结束
2、程序清单程序过长,可附主要部分)
#include<
string.h>
#include<
malloc.h>
/*malloc()等*/
limits.h>
/*INT_MAX等*/
iostream.h>
process.h>
/*exit()*/
#defineTRUE1
#defineFALSE0
#defineOK1#defineERROR0#defineINFEASIBLE-1
typedefintStatus;
/*Status
是函数的类型,其值是函数结果状态代码,如
OK等*/
〃定义无穷大
#defineINFINITYINT_MAX#defineMAX_VERTEX_NUM20typedefintVertexType;
typedefintInfoType;
typedefstructArcNode//表结点定义
InfoTypeinfo;
intadjvex;
//邻接点域,存放与Vi邻接的点在表头数组中的位置
ArcNode*nextarc;
//链域,指示依附于vi的下一条边或弧的结点,
II表头结点
//存放顶点信息
typedefstructVNode
{intdata;
}VNode,AdjList[MAX_VERTEX_NUM];
{II图的结构定义
IIe各顶点的最早发生时间
II各顶点发生的最晚发生时间
I*图的邻接表存储(存储结构定义)的基本操作*I
intLocateVex(MGraphG,VertexTypeu)
I*初始条件:
图G存在,u和G中顶点有相同特征*I
I*操作结果:
若G中存在顶点u,则返回该顶点在图中位置;
否则返回-1*Iinti;
for(i=0;
i<
G.vexnum;
++i)
if(u==G.vertices[i].data)
returni;
return-1;
};
{inti,j,k;
InfoTypevc;
VertexTypeva,vb;
ArcNode*p;
cout<
<
请输入图的顶点数,边数:
cin>
>
G.vexnum»
G.arcnum;
请输入"
G.vexnum<
个顶点的值(整数):
G.vexnum;
++i)/*构造顶点向量*I
cin»
G.vertices[i].data;
G.vertices[i].firstarc=NULL;
是否含有权值:
(若不含权值请输入0,否则输入1)\n"
G.Isquan;
G.lsquan)
请顺序输入每条弧的弧尾弧头"
endl;
else
请顺序输入每条弧的弧尾弧头以及弧的信息(以空格作为间隔):
for(k=0;
k<
++k)/*构造表结点链表*/
if(!
G.Isquan)
>
va»
vb;
vb»
vc;
i=LocateVex(G,va);
/*弧尾*/
j=LocateVex(G,vb);
/*弧头*/
p=(ArcNode*)malloc(sizeof(ArcNode));
p->
adjvex=j;
if(G.Isquan)
p->
info=vc;
info=0;
nextarc=G.vertices[i].firstarc;
/*插在表头*/
G.vertices[i].firstarc=p;
}returnOK;
{/*输出图G的信息*/
inti;
G.vexnum<
个顶点:
G.vertices[i].data<
endl<
G.arcnum<
条弧(边):
i++)
p=G.vertices[i].firstarc;
while(p)
{cout<
<
-"
->
G.vertices[p->
adjvex].data<
endl;
p=p->
nextarc;
〃system("
pause"
);
〃//////////////////////////////////////////////////////////////////
//
//建立栈相关的数据结构和函数//
{s.base=(int*)malloc(sizeof(int)*25);
{//向栈输入元素
if(s.top-s.base>
=s.stacksize)
s.base=(ElemType*)realloc(s.base,(s.stacksize+10)*sizeof(ElemType));
if(!
s.base)return0;
{s.top=s.base+s.stacksize;
s.stacksize+=10;
*s.top=e;
s.top++;
〃若栈不空,则删除S的栈顶元素,
〃用e返回其值,并返回OK;
否则返回ERROR
if(s.top==s.base)
e=*__s.top;
}//Pop;
intStackEmpty(Sqstacks)
〃若栈为空栈,则返回TRUE,否则返回FLASE
if(s.top==s.base)
return1;
elsereturn0;
/////////////////////////////////////////////////////////////////////////////
voidFindDegree(MGraphg,intindegree[])
indegree[i]
〃对=图中的各个顶点的入度进行统计,并将第i个顶点的入度数放入
for(i=0;
g.vexnum&
&
g.vexnum<
=25;
indegree[i]=0;
李星运是个SB"
for(intj=0;
j<
g.vexnum;
j++)
for(p=g.vertices[j].firstarc;
p!
=NULL;
nextarc)
indegree[p->
adjvex]++;
//对图进行拓扑排序,并输出拓扑排序的结果
StatusToopologicalSort(MGraphg)
{Sqstacks;
intcount=0;
FindDegree(g,indegree);
Initstack(s);
for(i=0;
if(indegree[i]==0)
Push(s,i);
〃将入度为0的顶点序号压入零入度栈
while(!
StackEmpty(s))〃如果零入度栈中还有结点
{Pop(s,i);
第"
结点"
\t"
g.vertices[i].data<
count++;
for(ArcNode*p=g.vertices[i].firstarc;
p;
{intk=p->
adjvex;
(--indegree[k]))
Push(s,k);
if(countvg.vexnum)〃将结点数与压入零结点栈进行比较{
不是连通图!
"
//拓扑序列
T)
Sqstacks;
FindDegree(g,indegree);
Initstack(s);
//用于存放零入度的结点栈
Initstack(T);
//若g不为空,则用T存放柘扑序列
if(indegree[i]==O)Push(s,i);
//初始化数组各结点的最早时间为0
for(i=0;
ve[i]=0;
StackEmpty(s))
Pop(s,i);
//将零入度结点栈中的结点弹出一个结点
Push(T,i);
〃将弹出的结点序列压入拓扑序列栈T中
nextarc){
intk=p->
//将入度为0的结点压入零入度栈中if(ve[i]+(p->
info)>
ve[k])
ve[k]=ve[i]+(p->
info);
if(countvg.vexnum)
//关键路径
StatusCriticalPath(MGraphg,SqstackT)
ToopologicalOrder(g,T))
拓扑排序不成功!
\n"
vl[i]=ve[i];
〃将各顶点的最晚发生时间都赋值为最早发生时间
StackEmpty(T))
for(Pop(T,i),p=g.vertices[i].firstarc;
intdut=p->
info;
if(vl[k]-dut<
vl[i])
vl[i]=vl[k]-dut;
〃如果顶点的最晚时间大于前一个顶点的最晚时间和其间权
值的差
for(intj=0;
++j)
for(p=g.vertices[i].firstarc;
intee=ve[j],el=vl[k]-dut;
g.vertices[j].data<
g.vertices[k].data<
voidmain()
cout<
各条弧的信息:
Display(g);
ToopologicalOrder(g,T);
CriticalPath(g,T);