首页 > 代码库 > _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网的关键路径