首页 > 代码库 > _DataStructure_C_Impl:AOE网的关键路径
_DataStructure_C_Impl:AOE网的关键路径
//_DataStructure_C_Impl:CriticalPath #include<stdio.h> #include<stdlib.h> #include<string.h> #include"SeqStack.h" //图的邻接表类型定义 typedef char VertexType[4]; typedef int InfoPtr; //定义为整型,为了存放权值 typedef int VRType; #define MaxSize 50 //最大顶点个数 typedef enum{DG,DN,UG,UN}GraphKind; //图的类型:有向图、有向网、无向图和无向网 //边结点的类型定义 typedef struct ArcNode{ int adjvex; //邻接点域,弧指向的顶点的位置 InfoPtr *info; //弧的权值 struct ArcNode *nextarc; //指示下一个与该顶点相邻接的顶点 }ArcNode; //头结点的类型定义 typedef struct VNode{ VertexType data; //用于存储顶点 ArcNode *firstarc; //指示第一个与该顶点邻接的顶点 }VNode,AdjList[MaxSize]; //图的类型定义 typedef struct{ AdjList vertex; int vexnum,arcnum; //图的顶点数目与弧的数目 GraphKind kind; //图的类型 }AdjGraph; //返回图中顶点相应的位置 int LocateVertex(AdjGraph G,VertexType v){ int i; for(i=0;i<G.vexnum;i++) if(strcmp(G.vertex[i].data,v)==0) return i; return -1; } //採用邻接表存储结构,创建有向网N void CreateGraph(AdjGraph *N){ int i,j,k,w; VertexType v1,v2; //定义两个顶点v1和v2 ArcNode *p; printf("请输入图的顶点数,边数(逗号分隔): "); scanf("%d,%d",&(*N).vexnum,&(*N).arcnum); printf("请输入%d个顶点的值:\n",N->vexnum); for(i=0;i<N->vexnum;i++){ scanf("%s",N->vertex[i].data); N->vertex[i].firstarc=NULL; //将相关联的顶点置为空 } printf("请输入弧尾和弧头(以空格作为间隔):\n"); for(k=0;k<N->arcnum;k++){ //建立边链表 scanf("%s%s%*c%d",v1,v2,&w); i=LocateVertex(*N,v1); j=LocateVertex(*N,v2); //j为弧头i为弧尾创建邻接表 p=(ArcNode *)malloc(sizeof(ArcNode)); p->adjvex=j; p->info=(InfoPtr*)malloc(sizeof(InfoPtr)); *(p->info)=w; //将p指向的结点插入到边表中 p->nextarc=N->vertex[i].firstarc; N->vertex[i].firstarc=p; } (*N).kind=DN; } //销毁无向图G void DestroyGraph(AdjGraph *G){ int i; ArcNode *p,*q; for(i=0;i<(*G).vexnum;++i){ //释放图中的边表结点 p=G->vertex[i].firstarc; //p指向边表的第一个结点 if(p!=NULL){ //假设边表不为空,则释放边表的结点 q=p->nextarc; free(p); p=q; } } (*G).vexnum=0; //将顶点数置为0 (*G).arcnum=0; //将边的数目置为0 } //输出图的邻接表 void DisplayGraph(AdjGraph G){ int i; ArcNode *p; printf("%d个顶点:\n",G.vexnum); for(i=0;i<G.vexnum;i++) printf("%s ",G.vertex[i].data); printf("\n%d条边:\n",G.arcnum); for(i=0;i<G.vexnum;i++) { p=G.vertex[i].firstarc; while(p) { printf("<%s,%s,%d> ",G.vertex[i].data,G.vertex[p->adjvex].data,*(p->info)); p=p->nextarc; } printf("\n"); } } //********************************************************* int ve[MaxSize]; //ve存放事件最早发生时间 /*採用邻接表存储结构的有向网N的拓扑排序,并求各顶点相应事件的最早发生时间ve*/ /*假设N无回路。则用用栈T返回N的一个拓扑序列,并返回1,否则为0*/ int TopologicalOrder(AdjGraph N,SeqStack *T){ int i,k,count=0; int indegree[MaxSize]; //数组indegree存储各顶点的入度 SeqStack S; ArcNode *p; //将图中各顶点的入度保存在数组indegree中 for(i=0;i<N.vexnum;i++) //将数组indegree赋初值 indegree[i]=0; for(i=0;i<N.vexnum;i++){ p=N.vertex[i].firstarc; while(p!=NULL){ k=p->adjvex; indegree[k]++; p=p->nextarc; } } //初始化栈S InitStack(&S); printf("拓扑序列:"); for(i=0;i<N.vexnum;i++) if(!indegree[i]) //将入度为零的顶点入栈 PushStack(&S,i); InitStack(T); //初始化逆拓扑排序顶点栈 for(i=0;i<N.vexnum;i++) //初始化ve ve[i]=0; while(!StackEmpty(S)){ //假设栈S不为空 PopStack(&S,&i); //从栈S将已拓扑排序的顶点i弹出 printf("%s ",N.vertex[i].data); PushStack(T,i); //i号顶点入逆拓扑排序栈T count++; //对入栈T的顶点计数 for(p=N.vertex[i].firstarc;p;p=p->nextarc){ //处理编号为i的顶点的每一个邻接点 k=p->adjvex; //顶点序号为k if(--indegree[k]==0) //假设k的入度减1后变为0,则将k入栈S PushStack(&S,k); if(ve[i]+*(p->info)>ve[k]) //计算顶点k相应的事件的最早发生时间 ve[k]=ve[i]+*(p->info); } } if(count<N.vexnum){ printf("该有向网有回路\n"); return 0; }else return 1; } //输出AOE网N的关键路径 int CriticalPath(AdjGraph N){ int vl[MaxSize]; //事件最晚发生时间 SeqStack T; int i,j,k,e,l,dut,value,count,e1[MaxSize],e2[MaxSize]; ArcNode *p; if(!TopologicalOrder(N,&T)) //假设有环存在,则返回0 return 0; value=http://www.mamicode.com/ve[0];>#pragma once #include<stdio.h> #include<stdlib.h> #define StackSize 100 typedef int DataType; //栈元素类型定义 typedef struct{ DataType stack[StackSize]; int top; }SeqStack; //将栈初始化为空栈仅仅须要把栈顶指针top置为 void InitStack(SeqStack *S){ S->top=0;//把栈顶指针置为0 } //推断栈是否为空。栈为空返回1,否则返回0 int StackEmpty(SeqStack S){ if(S.top==0) return 1; else return 0; } //取栈顶元素。将栈顶元素值返回给e,并返回1表示成功;否则返回0表示失败。 int GetTop(SeqStack S,DataType *e){ if(S.top<=0){ //在取栈顶元素之前。推断栈是否为空 printf("栈已经空!\n"); return 0; }else{ *e=S.stack[S.top-1]; //在取栈顶元素 return 1; } } //将元素e进栈。元素进栈成功返回1,否则返回0 int PushStack(SeqStack *S,DataType e){ if(S->top>=StackSize){ //在元素进栈前,推断是否栈已经满 printf("栈已满。不能进栈!\n"); return 0; }else{ S->stack[S->top]=e; //元素e进栈 S->top++; //改动栈顶指针 return 1; } } //出栈操作。将栈顶元素出栈。并将其赋值给e。出栈成功返回1。否则返回0 int PopStack(SeqStack *S,DataType *e){ if(S->top<=0){ //元素出栈之前,推断栈是否为空 printf("栈已经没有元素,不能出栈!\n"); return 0; }else{ S->top--; //先改动栈顶指针。即出栈 *e=S->stack[S->top]; //将出栈元素赋值给e return 1; } } //求栈的长度。即栈中元素个数,栈顶指针的值就等于栈中元素的个数 int StackLength(SeqStack S){ return S.top; } //清空栈的操作 void ClearStack(SeqStack *S){ S->top=0; }
_DataStructure_C_Impl:AOE网的关键路径
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。