数据结构课设的初步程序

#include<stdio.h>
#include<string.h>
#include<malloc.h>
#include<stdlib.h>
#include<iostream.h>
#define INFINITY 35542//用整型最大代替正无穷
#define NULL 0
#define FALSE 0
#define TRUE 1
#define ERROR 0
#define WRONG 0
#define OVERFLOW 0
#define M  10
#define MAX 20
#define MAXV 100
#define MAX_NAME 9
#define MAX_INFO 20
#define OK 1
#define STACK_INIT_SIZE 50

struct VertexType
{
 char data[3];/*顶点值*/;
 int info;/*弧的长度*/
 struct VertexType *next;/*顶点的下一个指针*/
};
typedef int ElemType;
typedef int Status;
typedef int VRType;
typedef char InfoType;//弧的相关信息类型
#define MAX_VERTEX_NUM 26//最大顶点个数
enum GraphKind{DG,DN,UDG,UDN};//{有向图,有向网,无向图,无向网}
typedef struct
{
 VRType adj;//顶点关系类型
 InfoType * info;//该弧相关信息的指针
}ArcCell,AdjMatrix[MAX_VERTEX_NUM][MAX_VERTEX_NUM];
struct MGraph
{
 VertexType vexs[MAX_VERTEX_NUM];//顶点向量
 AdjMatrix arcs;//邻接矩阵
 int vexnum,arcnum;//图当前顶点数和弧数
 GraphKind kind;
};

//
typedef struct Arcnode
{
 int adjvex;
 int weight;
 struct Arcnode* nextarc;
}Arcnode;//边表结点
typedef struct vnode
{
 int vertex;
 Arcnode* firstedge;
}vertexnode;//顶点表结点
typedef vertexnode adj_list[MAX];//adj_list是邻接表类型
typedef struct adjlist_graph
{
 int Arcnodes, edges;//图中顶点数和边数
 adj_list adjlist;//邻接表
 
}algraph;
typedef struct
{
 int u;          /*边的起始顶点*/
 int v;   /*边的终止顶点*/
 int w;   /*边的权值*/
}edge;

void visit(VertexType ver);
void Input(VertexType &ver);
void InputArc(InfoType *&arc);
void OutputArc(InfoType *arc);
int LocateVex(MGraph G,VertexType u);//返回顶点在图中的位置
void CreateDG(MGraph &G);//采用数组表示法,构造有向图
void CreateDN(MGraph &G);//构造有向网
void CreateUDG(MGraph &G);//构造无向图
void CreateUDN(MGraph &G);//构造无向网
void CreateGraph(MGraph &G);//构造图
void CreateUDG_ALG(algraph* g);//建立无向图的邻接表
void CreateUDN_ALG(algraph* g);//建立无向网的邻接表
void CreateDG_ALG(algraph* g);//建立有向图的邻接表
void CreateDN_ALG(algraph* g);//建立有向网的邻接表
void dispgraph(algraph* g);//输出邻接表
void Display(MGraph G);//输出邻接矩阵存储结构图
void InsertVex(MGraph &G,VertexType v);//在图中插入新的结点
Status InsertArc(MGraph &G,VertexType v,VertexType w);//在图中插入弧
void DestroyGraph(MGraph &G);
Status PutVex(MGraph &G,VertexType v,VertexType value);
void DFS(algraph * g);
void BFS(algraph * g);
void prim(MGraph g,int v);
void sortedge(MGraph g,edge E[]);    /*从邻接矩阵产生权值递增的边集*/
void  kruskal(edge E,int n,int e);


void Input(VertexType &ver)
{
 scanf("%s",&ver.data);
}
void visit(VertexType ver)
{
 printf("%s",ver.data);
}
int LocateVex(MGraph G,VertexType u)
{ //返回该结点在图中的位置
 int i;
 for(i=0;i<G.vexnum;i++)
  if(strcmp(u.data,G.vexs[i].data)==0)
   return i;
  return 0;
}
void InputArc(InfoType *&arc)
{
 char s[MAX_INFO];//临时存放空间
 int m;
 printf("请输入该弧的相关信息:",MAX_INFO);
 gets(s);
 m=strlen(s);
 if(m)
 {
  arc=(char *)malloc((m+1)*sizeof(char));//动态生成相关信息存储空间
  strcpy(arc,s);
 }
}
void OutputArc(InfoType *arc)
{
 printf("%s/n",arc);
}
VertexType GetVex(MGraph G,int v)
{
 if(v>=G.vexnum||v<0)
  exit(OVERFLOW);
 return G.vexs[v];//返回顶点的信息
}
void CreateDG(MGraph &G)
{
 int i,j,k,IncInfo;//IncInfo为0则弧不包括相关信息
 VertexType v1,v2;
 printf("请输入有向图G的顶点数,弧数,弧是否有相关信息(是:1否:0):");
 scanf("%d%d%d",&G.vexnum,&G.arcnum,&IncInfo);
 printf("请输入%d个顶点的值/n",G.vexnum,MAX_NAME);
 for(i=0;i<G.vexnum;i++)//构造顶点向量
  Input(G.vexs[i]);
 for(i=0;i<G.vexnum;i++)
  for(j=0;j<G.vexnum;j++)
  {
   G.arcs[i][j].adj=0;//图,不相邻
   G.arcs[i][j].info=NULL;//无相关信息
  }
  
  printf("请输入%d条弧的弧尾,弧头:/n",G.arcnum);
  for(k=0;k<G.arcnum;k++)
  {
   scanf("%s%s*%c",v1.data,v2.data);
   i=LocateVex(G,v1);//弧尾的序号
   j=LocateVex(G,v2);//弧头的序号
   G.arcs[i][j].adj=1;//有向图
   if(IncInfo)
   {
    InputArc(G.arcs[i][j].info);
   }
   G.kind=DG;
  }
}
void CreateDN(MGraph &G)
{ //采用数组表示法,构造有向网G
 int i,j,k,IncInfo;
 VRType w;//顶点关系类型
 VertexType v1,v2;
 printf("请输入有向网G的顶点数,弧数,弧是否有相关信息(是:1否:0)");
 scanf("%d%d%d",&G.vexnum,&G.arcnum,&IncInfo);
 printf("请输入%d个顶点的值:/n",G.vexnum);
 for(i=0;i<G.vexnum;i++)
  Input(G.vexs[i]);
 for(i=0;i<G.vexnum;i++)
  for(j=0;j<G.vexnum;j++)
  {
   G.arcs[i][j].adj=INFINITY;//网,不相邻
   G.arcs[i][j].info=NULL;
  }
  printf("请输入%d条弧的弧尾,弧头,权值:/n",G.arcnum);
  for(k=0;k<G.arcnum;k++)
  {
   scanf("%s%s%d%*c",v1.data,v2.data,&w);
   i=LocateVex(G,v1);//弧尾序号
   j=LocateVex(G,v2);//弧头序号
   G.arcs[i][j].adj=w;//有向网
   if(IncInfo)//有相关信息
    InputArc(G.arcs[i][j].info);
   //动态生成存储空间,输入弧的相关信息
  }
  G.kind=DN;
  
}
void CreateUDG(MGraph &G)
{ //采用数组构造无向图
    int i,j,k,IncInfo;
    VertexType v1,v2;
    printf("请输入无向图G的顶点数,边数,边是否有相关信息(是:1否:0):");
 scanf("%d%d%d",&G.vexnum,&G.arcnum,&IncInfo);
    printf("请输入%d个顶点的值:/n",G.vexnum);
    for(i=0;i<G.vexnum;i++)
  Input(G.vexs[i]);
    for(i=0;i<G.vexnum;i++)
  for(j=0;j<G.vexnum;j++)
  { G.arcs[i][j].adj=0;//图不相邻
  G.arcs[i][j].info=NULL;
  }
  printf("请输入%d条边的顶点1顶点2:/n",G.arcnum);
  for(k=0;k<G.arcnum;k++)
  { 
   scanf("%s%s%*c",v1.data,v2.data);
   i=LocateVex(G,v1);//顶点1的序号
   j=LocateVex(G,v2);//顶点2的序号
   G.arcs[i][j].adj=1;//图
   if(IncInfo)//有相关信息
    InputArc(G.arcs[i][j].info);//动态生成存储空间,输入弧的相关信息
   G.arcs[j][i]=G.arcs[i][j];
  }
  G.kind=UDG;
  
}
void CreateUDN(MGraph &G)
{
 int i,j,k,IncInfo;
 VRType w;
 VertexType v1,v2;
 printf("请输入无向网的顶点数,边数,边是否含相关结点信息(1,是;0,否)");
 scanf("%d%d%d",&G.vexnum,&G.arcnum,&IncInfo);
 printf("请输入%d个结点的值:/n",G.vexnum);
 for(i=0;i<G.vexnum;i++)
  Input(G.vexs[i]);
 for(i=0;i<G.vexnum;i++)
  for(j=0;j<G.vexnum;j++)
  {
   G.arcs[i][j].adj=INFINITY;//网,不相邻
   G.arcs[i][j].info=NULL;//无相关信息
  }
  printf("请输入%d条边的顶点1顶点2及连接它们边的权值:/n",G.arcnum);
  for(k=0;k<G.arcnum;k++)
  { 
   scanf("%s%s%d%*c",v1.data,v2.data,&w);
   i=LocateVex(G,v1);
   j=LocateVex(G,v2);
   G.arcs[i][j].adj=w;//网
   if(IncInfo)
    InputArc(G.arcs[i][j].info);
   G.arcs[j][i]=G.arcs[i][j];
  }
  G.kind=UDN;
}

void ShowMainMenu()
{
 cout<<"/n";
 cout<<"  ***************图的基本操作及应用******************/n";
 cout<<"  *  1 无向图的基本操作及应用                      */n";
 cout<<"  *  2 无向网的基本操作及应用                      */n";
 cout<<"  *  3 有向图的基本操作及应用                      */n";
 cout<<"  *  4 有向网的基本操作及应用                      */n";
 cout<<"  *  5 退出                                        */n";
 cout<<"  ***************************************************/n";
}

void Display(MGraph G)
{
 int i,j;
 char s[7]="无向图",s1[3]="边";
 switch(G.kind)
 {
 case DG:strcpy(s,"有向图");
  strcpy(s1,"弧");
  break;
 case DN:strcpy(s,"有向网");
  strcpy(s1,"弧");
  break;
 case UDG:strcpy(s,"无向图");
 case UDN:strcpy(s,"无向网");
 }
 printf("%d个顶点%d条%s的%s,顶点依次是:",G.vexnum,G.arcnum,s1,s);
 for(i=0;i<G.vexnum;i++)
 {
  visit(GetVex(G,i));
  printf("   ");
 }
 printf("/nG.arcs.adj:/n");
 for(i=0;i<G.vexnum;i++)
 {
  for(j=0;j<G.vexnum;j++)
   printf("%7d",G.arcs[i][j].adj);
  printf("/n");
 }
 printf("G.arcs.info:/n");
 if(G.kind<2)
  printf("弧尾 弧头 该%s的信息:/n",s1);
 for(i=0;i<G.vexnum;i++)
  if(G.kind<2)//有向
  {
   for(j=0;j<G.vexnum;j++)
    if(G.arcs[i][j].info)
    {
     printf("%5s%5s",G.vexs[i].data,G.vexs[j].data);
     OutputArc(G.arcs[i][j].info);
    }
  }
  else//无向
   for(j=i+1;j<G.vexnum;j++)
    if(G.arcs[i][j].info)
    { printf("%5s%5s",G.vexs[i].data,G.vexs[j].data);
    OutputArc(G.arcs[i][j].info);
    }    
}


/
void CreateUDG_ALG(algraph* g)
{
 Arcnode* newArcnode;
 int i, j, k;
 printf("请输入顶点数和边数: ");
 scanf("%d%d", &g->Arcnodes, &g->edges);
 printf("顶点数 = %d, 边数 = %d/n", g->Arcnodes, g->edges);
 for(i = 0; i < g->Arcnodes; i++)
 {
  g->adjlist[i].vertex = i;
  g->adjlist[i].firstedge = NULL;
 }
 for(k = 0; k < g->edges; k++)
 {
  printf("请输入新边: ");
  scanf("%d%d", &i, &j);
  printf("/n");
  newArcnode = (Arcnode* )malloc(sizeof(Arcnode));
  newArcnode->adjvex = j;
  newArcnode->weight = 0;
  newArcnode->nextarc = g->adjlist[i].firstedge;
  g->adjlist[i].firstedge = newArcnode;
  newArcnode = (Arcnode* )malloc(sizeof(Arcnode));
  newArcnode->adjvex = i;
  newArcnode->weight = 0;
  newArcnode->nextarc = g->adjlist[j].firstedge;
  g->adjlist[j].firstedge = newArcnode;
 }
}
void CreateUDN_ALG(algraph* g)
{
 Arcnode* newArcnode;
 int i, j, k,m;
 printf("请输入顶点数和边数: ");
 scanf("%d%d", &g->Arcnodes, &g->edges);
 printf("顶点数 = %d, 边数 = %d/n", g->Arcnodes, g->edges);
 for(i = 0; i < g->Arcnodes; i++)
 {
  g->adjlist[i].vertex = i;
  g->adjlist[i].firstedge = NULL;
 }
 for(k = 0; k < g->edges; k++)
 {
  printf("请输入新边和此边的权值: ");
  scanf("%d%d%d", &i, &j,&m);
  printf("/n");
  newArcnode = (Arcnode* )malloc(sizeof(Arcnode));
  newArcnode->adjvex = j;
  newArcnode->weight = m;
  newArcnode->nextarc = g->adjlist[i].firstedge;
  g->adjlist[i].firstedge = newArcnode;
  newArcnode = (Arcnode* )malloc(sizeof(Arcnode));
  newArcnode->adjvex = i;
  newArcnode->weight = m;
  newArcnode->nextarc = g->adjlist[j].firstedge;
  g->adjlist[j].firstedge = newArcnode;
 }
}
void CreateDG_ALG(algraph* g)
{
 Arcnode* newArcnode;
 int i, j, k;
 printf("请输入顶点数和边数: ");
 scanf("%d%d", &g->Arcnodes, &g->edges);
 printf("顶点数 = %d, 边数 = %d/n", g->Arcnodes, g->edges);
 for(i = 0; i < g->Arcnodes; i++)
 {
  g->adjlist[i].vertex = i;
  g->adjlist[i].firstedge = NULL;
 }
 for(k = 0; k < g->edges; k++)
 {
  printf("请输入新边: ");
  scanf("%d%d", &i, &j);
  printf("/n");
  newArcnode = (Arcnode* )malloc(sizeof(Arcnode));
  newArcnode->adjvex = j;
  newArcnode->weight = 0;
  newArcnode->nextarc = g->adjlist[i].firstedge;
  g->adjlist[i].firstedge = newArcnode;
 }
}
void CreateDN_ALG(algraph* g)
{
 Arcnode* newArcnode;
 int i, j, k,m;
 printf("请输入顶点数和边数: ");
 scanf("%d%d", &g->Arcnodes, &g->edges);
 printf("顶点数 = %d, 边数 = %d/n", g->Arcnodes, g->edges);
 for(i = 0; i < g->Arcnodes; i++)
 {
  g->adjlist[i].vertex = i;
  g->adjlist[i].firstedge = NULL;
 }
 for(k = 0; k < g->edges; k++)
 {
  printf("请输入新边和此边的权值: ");
  scanf("%d%d%d", &i, &j,&m);
  printf("/n");
  newArcnode = (Arcnode* )malloc(sizeof(Arcnode));
  newArcnode->adjvex = j;
  newArcnode->weight = m;
  newArcnode->nextarc = g->adjlist[i].firstedge;
  g->adjlist[i].firstedge = newArcnode;
 }
}
void dispgraph(algraph* g)
{
 Arcnode* Arcnode;
 int i;
 for(i = 0; i < g->Arcnodes; i++)
 {
  Arcnode = g->adjlist[i].firstedge;
  printf("g->adjlist[%d] = %d: ", i, g->adjlist[i].vertex);
  while(Arcnode != NULL)
  {
   printf("%d %d/t", Arcnode->adjvex, Arcnode->weight);
   Arcnode = Arcnode->nextarc;
  }
  printf("/n");
 }
}
/
int visited[MAX];
void DFS(algraph * g,int v)
{
 Arcnode *p;
 visited[v]=1;
 printf("%3d",v);
 p=g->adjlist[v].firstedge;
 while(p!=NULL)
 {
  if(visited[p->adjvex]==0)
   DFS(g,p->adjvex);
  p=p->nextarc;
 }
}
void BFS(algraph * g,int u)
{
 Arcnode *p;
 int queue[MAX],front=0,rear=0;/*定义循环列队并初始化*/
 int visited[MAX];/*定义存放结点访问标记的数组*/
 int w,i;
 for(i=0;i<g->Arcnodes;i++) visited[i]=0;/*访问标记的数组的初始化*/
 printf("%3d",u);/*输出被访问顶点的编号*/
 visited[u]=1;/*置已被访问标记*/
 rear=(rear+1)%MAX;
 queue[rear]=u;/*V进队*/
 while(front!=rear)/*若队列不为空时循环*/
 {
  front=(front+1)%MAX;
  w=queue[front];  /*出队并赋给w*/
  p=g->adjlist[w].firstedge;/*找与顶点w邻接的第一个顶点*/
  while(p!=NULL)
  {
   if(visited[p->adjvex]==0)/*若当前结点未被访问*/
   {
    printf("%3d",p->adjvex);/*访问相邻结点*/
    visited[p->adjvex]=1;/*置该顶点已被访问的标记*/
    rear=(rear+1)%MAX;/*该顶点进队*/
    queue[rear]=p->adjvex;
   }
   p=p->nextarc;/*找下一个邻接顶点*/
  }
 }
 printf("/n");
}
void prim(MGraph g,int v)
{
 int lowcost[MAX],min,n=g.vexnum;
 int closest[MAX],i,j,k;
 for(i=0;i<n;i++)
 {
  lowcost[i]=g.arcs[v][i].adj;  /*给lowcost[]和closest[]置初值,lowcost[]存放权值,closest[]存放顶点信息*/
  closest[i]=v;
 }
 for(i=1;i<n;i++)     /*找出n-1个顶点*/
 {
  min=INFINITY;
  for(j=0;j<n;j++)    /*在V-U中找出离U最近的顶点K*/
   if(lowcost[j]!=0&&lowcost[j]<min)
   {
    min=lowcost[j];k=j;
   }
   printf("边(%d,%d)权为:%d/n",closest[k],k,min);
   lowcost[k]=0;    /*标记K已经加入U中*/
   for(j=0;j<n;j++)   /*修改数组lowcost和closest*/
    if(g.arcs[k][j].adj !=0&&g.arcs[k][j].adj<lowcost[j])
    {
     lowcost[j]=g.arcs[k][j].adj ;
     closest[j]=k;
    }
 }
}
void sortedge(MGraph g,edge E[])    /*从邻接矩阵产生权值递增的边集*/
{
 int i,j,k=0;
 edge temp;
 for(i=0;i<g.vexnum;i++)
  for(j=0;j<g.vexnum;j++)
   if(g.arcs[i][j].adj <INFINITY)
   {
    E[k].u=i;
    E[k].v=j;
    E[k].w=g.arcs[i][j].adj ;
    k++;
   }
   for(i=1;i<k;i++)        /*按权值递增有序进行直接插入排序*/
   {
    temp=E[i];
    j=i-1;         /*从右向左在有序区e[0....i-1]中找e[i]的插入位置*/
    while(j>=0&&temp.w<E[j].w)
    {
     E[j+1]=E[j];     /*将权值大于e[i].w的记录后移*/
     j--;
    }
    E[j+1]=temp;         /*在j+1处插入e[i]*/
   }
}
void  kruskal(edge E[],int n,int e)
{
 int i,j,m1,m2,sn1,sn2,k;
 int vset[MAX];
 for(i=0;i<n;i++)vset[i]=i;  /*初始化辅助数组*/
 k=1;       /*K表示当前构造的第几条边,初值为1*/
 j=0;       /*e中边的下标,初始值为0*/
 while(k<n)      /*生成的边数小于n时循环*/
 {
  m1=E[j].u;
  m2=E[j].v;     /*取一条边的头尾结点*/
  sn1=vset[m1];
  sn2=vset[m2];    /*分别得到两个顶点所属的集合编号*/
  if(sn1!=sn2)
  {
   printf("(%d,%d):%d/n",m1,m2,E[j].w);
   k++;     /*生成边数增1*/
   for(i=0;i<n;i++)  /*两个集合统一编号*/
    if(vset[i]==sn2) /*集合编号为sn2的改为sn1*/
     vset[i]=sn1;
  }
  j++;      /*扫描下一条边*/
 }
}
/
typedef struct STACK /*定义栈类型*/
{
 ElemType *base;
 ElemType *top;
 int stacksize;
 int length;
}SqStack,*Stack;
void InitStack(Stack *S) /*初始化栈*/
{
 *S=(SqStack *)malloc(sizeof(SqStack));
 (*S)->base=(ElemType *)malloc(STACK_INIT_SIZE*sizeof(ElemType));
 if(!(*S)->base)exit(-1);
 (*S)->top=(*S)->base;
 (*S)->stacksize=STACK_INIT_SIZE;
 (*S)->length=0;
}
Status DestroyStack(Stack *S) /* 销毁栈*/
{
 free((*S)->base);
 free((*S));
 return 1;
}
Status StackEmpty(SqStack S) /*判断栈空否*/
{
 if(S.top==S.base) return 1;
 else
  return 0;
}
void Push(Stack *S,ElemType e)  /*把数据压入栈*/
{
 if((*S)->top - (*S)->base>=(*S)->stacksize)
 {
  (*S)->base=(ElemType *) realloc((*S)->base,
   ((*S)->stacksize + 10) * sizeof(ElemType));
  if(!(*S)->base)exit(-1);
  (*S)->top=(*S)->base+(*S)->stacksize;
  (*S)->stacksize +=10;
 }
 *((*S)->top++)=e;
 ++(*S)->length;
}
Status Pop(Stack *S,ElemType *e)/*删除栈顶元素*/
{
 if((*S)->top==(*S)->base) return 0;
 *e=*((*S)->top-1);
 --(*S)->length;
 (*S)->top--;
 return 1;
}
void FindInDegree(algraph G, int indegree[])//求入度操作
{
 int i;
 for (i = 1; i <= G.Arcnodes; i++)
 {
  indegree[i] = 0;
 }
 for (i = 1; i <= G.Arcnodes; i++)
 {
  while (G.adjlist[i].firstedge)
  {
   indegree[G.adjlist[i].firstedge->adjvex]++;
   G.adjlist[i].firstedge = G.adjlist[i].firstedge->nextarc;
  }
 }
}
void FindInDegree1(MGraph G,int *indegree)/*对各顶点求入度,邻接矩阵的列*/
{
 int i,j;
 for(i=0;i<G.vexnum;i++)
  for(j=0;j<G.vexnum;j++)
   if(G.arcs[j][i].adj==1) indegree[i]++;
}
void CreatGraph(algraph *G)//构件图
{
 int m, n, i;
 Arcnode *p;
 printf("请输入顶点数和边数:");
 scanf("%d%d",&G->Arcnodes,&G->edges);
 for (i = 1; i <= G->Arcnodes; i++)
 {
  G->adjlist[i].vertex = i;
  G->adjlist[i].firstedge = NULL;
 }
 for (i = 1; i <= G->edges; i++)       //输入存在边的点集合
 {
  printf("/n请输入存在边的两个顶点的序号:");
  scanf("%d%d",&n,&m);
  while (n < 0 || n > G->Arcnodes || m < 0 || m > G->Arcnodes)
  {
   printf("输入的顶点序号不正确 请重新输入:");
   scanf("%d%d",&n,&m);
  }
  p = (Arcnode*)malloc(sizeof(Arcnode));
  if (p == NULL)
  {
   printf("memory allocation failed,goodbey");
   exit(1);
  }
  p->adjvex = m;
  p->nextarc = G->adjlist[n].firstedge;
  G->adjlist[n].firstedge = p;
 }
 printf("建立的邻接表为:/n");          //输出建立好的邻接表
 for(i = 1; i <= G->Arcnodes; i++)
 {
  printf("%d",G->adjlist[i].vertex);
  for(p = G->adjlist[i].firstedge; p; p = p->nextarc)
   printf("%3d",p->adjvex);
  printf("/n");
 }
}
void TopologicalSort(algraph G)       //进行拓扑排序
{
 int indegree[M];
 int i, k, n;
 int count = 0;
 Arcnode *p;
 Stack S;
 FindInDegree(G, indegree);
 InitStack(&S);
 for (i = 1; i <= G.Arcnodes; i++)
 {
  printf("第%d个点的入度为%d /n", i, indegree[i]);
 }
 printf("/n");
 for ( i = 1; i <= G.Arcnodes; i++)
 {
  if (!indegree[i])
   Push(&S,i);
 }
 printf("进行拓扑排序输出顺序为:");         //输出结果
 while(!StackEmpty(*S))
 {
  Pop(&S,&n);
  printf("%4d",G.adjlist[n].vertex);
  count++;
  for (p = G.adjlist[n].firstedge;  p != NULL;  p = p->nextarc)
  {
   k = p->adjvex;
   if (!(--indegree[k]))
   {
    Push(&S,k);
   }
  }
  
 }
 printf("/n");
 
 if (count < G.Arcnodes)
 {
  printf("出现错误/n");
 }
 else
 {
  printf("排序成功/n");
 }
}
int *ve,*vl;/*最早发生时间和最迟发生时间数组*/
int TopologicalOrder(MGraph G,Stack *T)/*有向图采用矩阵存储结构,无回路返回1*/
{
 Stack S;
 int i,k,count,*indegree;
 VertexType *p;
 indegree=(int *)malloc(G.vexnum*sizeof(int));/*度数组空间*/
 ve=(int *)malloc(G.vexnum*sizeof(int));/*最早发生时间的数组空间*/
 for(i=0;i<G.vexnum;i++)
  indegree[i]=0;/*初始化*/
 for(i=0;i<G.vexnum;i++)
  ve[i]=0;/*初始化*/
 FindInDegree1(G,indegree);/*求各点入度*/
 InitStack(&S);/*初始化栈*/
 InitStack(T);
 for(i=0;i<G.vexnum;++i)
  if(!indegree[i]) Push(&S,i);/*入度为0进栈*/
  count=0;/*对输出顶点计数*/
  while(!StackEmpty(*S))
  {
   Pop(&S,&i);/*拿出入度为0 的*/
   Push(T,i);/*i号顶点入T栈*/
   ++count;/*计数*/
   p=G.vexs[i].next;
   while(p)
   {
    k=LocateVex(G,*p);
    if(!(--indegree[k])) Push(&S,k);/*减一后为0就入栈*/
    if(ve[i]+G.arcs[i][k].adj>ve[k]) ve[k]=ve[i]+G.arcs[i][k].adj ;/*在它的所有邻点中找出能使最大*/
    p=p->next;
   }
  }
  DestroyStack(&S);
  free(indegree);
  if(count<G.vexnum) return 0;/*有向图有回路*/
  else return 1;
}
int CriticalPath(MGraph G)/*G为有向网,输出G的各项关键活动*/
{
 Stack T;
 int j,dut,e1,e2,k=0;
 char tag;
 VertexType *p;
 if(!TopologicalOrder(G,&T)) return 0;/*有回路就不做*/
 vl=(int *)malloc(G.vexnum*sizeof(int));/*最迟发生时间数组空间*/
 for(j=0;j<G.vexnum;j++)/*初始化事件的最迟发生时间*/
  vl[j]=ve[j];
 while(!StackEmpty(*T))/*按拓扑逆序求各事件的 vl 值*/
 {
  Pop(&T,&j);/*从最后一个开始*/
  p=G.vexs[j].next;
  while(p)
  {
   k=LocateVex(G,*p);/*邻点的位置*/
   dut=G.arcs[j][k].adj;/*两点间的长度*/
   if(vl[k]-dut>vl[j]) vl[j]=vl[k]-dut;
   p=p->next;
  }
 }
 for(j=0;j<G.vexnum;j++)
  printf("事件 %s 的最早和最迟发生时间分别为 *%d* 和 *%d*/n",G.vexs[j].data,ve[j],vl[j]);
 printf("关键活动为:/n");
 for(j=0;j<G.vexnum;j++)/*求关键活动和它的值,顶点是事件,弧是活动*/
 {
  p=G.vexs[j].next;/*每个事件要依赖它的邻点才可知是否最早=最迟*/
  while(p)
  {
   k=LocateVex(G,*p);/*邻点的位置*/
   dut=p->info;/*弧长*/
   e1=ve[j];e2=vl[k]-dut;/*如果最早开始时间=最迟开始时间,最迟为邻点减去弧长*/
   if(e1==e2) tag='*';
   else tag=' ';
   if(tag=='*')
    printf("*%s* 到 *%s* 长度为*%d* 发生时间为 *%d*/n",G.vexs[j].data,G.vexs[k].data,dut,e2);
   p=p->next;
  }
 }
 free(vl);free(ve);DestroyStack(&T);
 return 1;
}

void ppath(int path[],int i,int v0)
{
 int k;
 k=path[i];
 if(k==v0)
  return;
 ppath(path,k,v0);
 printf("%d",k);
}
void DisPath(int dist[],int path[],int s[],int n,int v0)/*由path计算最短路径*/
{
 int i;
 printf("path:");
 for(i=0;i<n;i++)
  printf("%3d",path[i]);
 printf("/n");
 for(i=0;i<n;i++)
  if(s[i]==1&&i!=v0)
  {
   printf("从%d到%d的最短路径长度为:%d/t路径为:",v0,i,dist[i]);
   printf("%d",v0);
   ppath(path,i,v0);
   printf("%d/n",i);
  }
  else
   printf("从%d到%d不存在路径/n",v0,i);
}
void Dijkstra(MGraph g,int v0)
{
 int dist[MAXV],path[MAXV];
 int s[MAXV];
 int mindis,i,j,u,n=g.vexnum ;
 for(i=0;i<n;i++)
 {
  dist[i]=g.arcs[v0][i].adj;
  s[i]=0;
  if(g.arcs[v0][i].adj<INFINITY)
   path[i]=v0;
  else
   path[i]=-1;
 }
 s[v0]=1;path[v0]=0;
 for(i=0;i<n;i++)
 {
  mindis=INFINITY;
  u=-1;
  for(j=0;j<n;j++)
   if(s[j]==0&&dist[j]<mindis)
   {
    u=j;
    mindis=dist[j];
   }
   s[u]=1;
   for(j=0;j<n;j++)
    if(s[j]==0)
     if(g.arcs[u][j].adj<INFINITY&&dist[u]+g.arcs[u][j].adj<dist[j])
     {
      dist[j]=dist[u]+g.arcs[u][j].adj;
      path[j]=u;
     }
 }
 printf("输出最短路径:/n");
 DisPath(dist,path,s,n,v0);
}
void UDG1()
{
 MGraph MG;
 algraph * ALG=new algraph;
 int n;
 do
 {
  cout<<"/n";
  cout<<"  ***************无向图的基本操作及应用***************/n";
  cout<<"  *  1 创建无向图的邻接矩阵                         */n";
  cout<<"  *  2 创建无向图的邻接表                           */n";
  cout<<"  *  3 无向图的深度优先遍历                         */n";
  cout<<"  *  4 无向图的广度优先遍历                         */n";
  cout<<"  *  5 退出                                         */n";
  cout<<"  ****************************************************/n";
  cin>>n;
  switch(n){
  case 1:
   CreateUDG(MG);
   Display(MG);
   break;
  case 2:
   CreateUDG_ALG(ALG);
   dispgraph(ALG);
   break;
  case 3:
   CreateUDG_ALG(ALG);
   dispgraph(ALG);
   int v;
   printf("输入深度遍历的起始顶点:");
   scanf("%d",&v);
   printf("从顶点%d开始的DFS(递归算法):/n",v);
   DFS(ALG,v);
   break;
  case 4:
   CreateUDG_ALG(ALG);
   dispgraph(ALG);
   int u;
   printf("输入宽度遍历的起始顶点:");
   scanf("%d",&u);
   printf("从顶点%d开始的BFS:/n",u);
   BFS(ALG,u);
   break;
  default:
   if (n!=5)
    cout<<"错误,重新输入/n";
  }
 }while(n!=5);
}

void UDN1()
{
 MGraph MN;
 algraph * ALN=new algraph;
 int n;
 edge E[MAX];
 do{
  cout<<"/n";
  cout<<"  ***************无向网的基本操作及应用***************/n";
  cout<<"  *  1 创建无向网的邻接矩阵                         */n";
  cout<<"  *  2 创建无向网的邻接表                           */n";
  cout<<"  *  3 prim算法求最小生成树                         */n";
  cout<<"  *  4 kraskal算法求最小生成树                      */n";
  cout<<"  *  5 退出                                         */n";
  cout<<"  ****************************************************/n";
  cin>>n;
  switch(n){
  case 1:
   CreateUDN(MN);
   Display(MN);
   break;
  case 2:
   CreateUDN_ALG(ALN);
   dispgraph(ALN);
   break;
  case 3:
   CreateUDN(MN);
   int u;
   printf("输入起始顶点:");
   scanf("%d",&u);
   printf("/n");
   printf("普里母算法求解最小生成树的结果:");
   prim(MN,u);
   break;
  case 4:
   CreateUDN(MN);
   printf("克鲁斯卡尔算法求解最小生成树的结果:");
   sortedge(MN,E);
   kruskal(E,MN.vexnum,MN.arcnum);
   break;
  default:
   if (n!=5)
    cout<<"错误,重新输入/n";
  }
 }while(n!=5);
 
}

void DG1()
{
 MGraph MG;
 algraph * ALG=new algraph;
 algraph G;
 int n;
 do
 {
  cout<<"/n";
  cout<<"  ***************有向图的基本操作及应用***************/n";
  cout<<"  *  1 创建有向图的邻接矩阵                         */n";
  cout<<"  *  2 创建有向图的邻接表                           */n";
  cout<<"  *  3 拓扑排序                                     */n";
  cout<<"  *  4 退出                                         */n";
  cout<<"  ****************************************************/n";
  cin>>n;
  Stack *T=new Stack;
  switch(n){
  case 1:
   CreateDG(MG);
   Display(MG);
   break;
  case 2:
   CreateDG_ALG(ALG);
   dispgraph(ALG);
   break;
  case 3:
   CreatGraph(&G);
   TopologicalSort(G);
   break;
  default:
   if (n!=4)
    cout<<"错误,重新输入/n";
  }
 }while(n!=4);
}

void DN1()
{
 MGraph MN;
 algraph * ALN=new algraph;
 int n;
 do{
  cout<<"/n";
  cout<<"  ***************有向网的基本操作及应用***************/n";
  cout<<"  *  1 创建有向网的邻接矩阵                         */n";
  cout<<"  *  2 创建有向网的邻接表                           */n";
  cout<<"  *  3 关键路径                                     */n";
  cout<<"  *  4 单源顶点最短路径问题                         */n";
  cout<<"  *  5 退出                                         */n";
  cout<<"  ****************************************************/n";
  cin>>n;
  Stack *T=new Stack;
  switch(n){
  case 1:
   CreateDN(MN);
   Display(MN);
   break;
  case 2:
   CreateDN_ALG(ALN);
   dispgraph(ALN);
   break;
  case 3:
   CreateDN(MN);
   CriticalPath(MN);
   break;
  case 4:
   CreateDN(MN);
   int u;
   printf("输入起始顶点:");
   scanf("%d",&u);
   printf("/n");
   Dijkstra(MN,u);
   break;
  default:
   if (n!=5)
    cout<<"错误,重新输入/n";
  }
 }while(n!=5);
 
}

void main()
{
 int n;
 do{
  ShowMainMenu();
  cin>>n;
  switch(n){
  case 1:
   UDG1();
   break;
  case 2:
   UDN1();
   break;
  case 3:
   DG1();
   break;
  case 4:
   DN1();
   break;
  default:
   if (n!=5)
    cout<<"错误,重新输入/n";
  }
 }while(n!=5);
}

无向网里面的关键路径貌似运行有错误,请高手帮忙指点

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值