图实验6

来源:互联网 发布:吉威时代怎么样 知乎 编辑:程序博客网 时间:2024/06/14 09:30
#include<cstdio>#include<cstdlib>#define OVERFLOW  -2typedef int Status;typedef int Boolean;typedef int ElemType;#define MAX_VERTEX_NUM 20//图的邻接表存储结构 typedef int  VertexType;typedef struct ArcNode{    int adjvex;    struct ArcNode *nextarc;                }ArcNode;typedef struct{    VertexType data;    int indegree;    ArcNode *firstarc;       }VNode,AdjList[MAX_VERTEX_NUM];typedef struct{    AdjList vertices;    int vexnum,arcnum;      }ALGraph;int LocateVex(ALGraph G,VertexType u){    int i;    for(i=1;i<=G.vexnum;++i)      if(u==G.vertices[i].data)      return i;     return 0;    }// 图的建立 int CreateGraph(ALGraph &G) //成功建立返回1,不成功则返回0{    int i,j,k;     VertexType v1,v2;     ArcNode *newarc;printf("输入有向图顶点数和弧数:"); //输入顶点数和弧数scanf("%d %d",&G.vexnum,&G.arcnum); //输入并判断顶点数和弧数是否正确if(G.vexnum<0||G.arcnum<0||G.arcnum>G.vexnum*(G.vexnum-1)){            printf("顶点数或弧数不正确,有向图建立失败!\n");            return 0;         }printf("输入 %d 个顶点:",G.vexnum); //输入顶点名称for(i=0;i<G.vexnum;i++)       scanf("%d",&G.vertices[i].data); printf("共有%d个顶点:   ",G.vexnum);//输出顶点名称for(i=0;i<G.vexnum;i++)printf("%d   ",G.vertices[i].data);for(i=0;i<G.vexnum;i++) //邻接表初始化{            G.vertices[i].firstarc=NULL;G.vertices[i].indegree=0;        }printf("\n输入 %d 条边:vi vj\n",G.arcnum); //输入有向图的边for(k=0;k<G.arcnum;k++){           scanf("%d %d",&v1,&v2); //v1是弧的起点(先决条件),v2是弧的终点i=LocateVex(G,v1);j=LocateVex(G,v2); //定位顶点并判断顶点是否存在if(i>=G.vexnum){                    printf("顶点 %d 不存在,有向图建立失败!\n",v1);                    return 0;                 }            if(j>=G.vexnum){                   printf("顶点 %d 不存在,有向图建立失败!\n",v2);                    return 0;                 }newarc=(ArcNode*)malloc(sizeof(ArcNode)); //前插法建顶点链表newarc->adjvex=j;if(G.vertices[i].firstarc==NULL){newarc->nextarc=NULL;G.vertices[i].firstarc=newarc;                 }else{newarc->nextarc=G.vertices[i].firstarc->nextarc;G.vertices[i].firstarc->nextarc=newarc;                 }G.vertices[j].indegree++; //对应顶点入度计数加1}printf("有向图建立成功!\n");printf("-------------------------\n");return 1;}// 图的建立 //7.按邻接表方式输出有向图 void PrintGraph(ALGraph G){    int i;ArcNode *p;printf("输出有向图:\n");for(i=0; i<G.vexnum; i++){            printf("\n顶点:%d   ",G.vertices[i].data);printf("入度:%3d\n",G.vertices[i].indegree);p=G.vertices[i].firstarc;printf("邻接点:");while(p!=NULL){                    printf("%d   ",G.vertices[p->adjvex].data);p=p->nextarc;                 }printf("\n");printf("-------------------------\n");}}int FirstAdjVex(ALGraph G,VertexType v){   ArcNode *p;   int v1;   v1=LocateVex(G,v);   p=G.vertices[v1].firstarc;   if(p)     return p->adjvex;   else      return 0;  } int NextAdjVex(ALGraph G,VertexType v,VertexType w){   ArcNode *p;   int v1,w1;   v1=LocateVex(G,v);   w1=LocateVex(G,w);   p=G.vertices[v1].firstarc;   while(p&&p->adjvex!=w1)   p=p->nextarc;   if(!p||!p->nextarc)    return 0;   else      return p->nextarc->adjvex;    }Boolean visited[MAX_VERTEX_NUM];void DFS(ALGraph G,int v) // 深度优先遍历 {    int w;    visited[v]=1;    printf("%d ",G.vertices[v].data);    for(w=FirstAdjVex(G,G.vertices[v].data);w>=1;w=NextAdjVex(G,G.vertices[v].data,G.vertices[w].data))      if(!visited[w])    DFS(G,w);}void DFSTraverse(ALGraph G)// 深度优先遍历 {   int v;   for(v=0;v<=G.vexnum;v++)     visited[v]=0;   for(v=0;v<G.vexnum;v++)/*****v是从0开始循环*****/     if(!visited[v])     DFS(G,v);   printf("\n");     }typedef int QElemType;typedef struct QNode{    QElemType data;    struct QNode *next;      }QNode,*QueuePtr;typedef struct LinkQueue{  QueuePtr front,rear;        }LinkQueue;void InitQueue(LinkQueue &Q){   if(!(Q.front=Q.rear=(QueuePtr)malloc(sizeof(QNode))))     exit(OVERFLOW);   Q.front->next=NULL;   }Status QueueEmpty(LinkQueue Q){   if(Q.front->next==NULL)    return 1;   else  return 0;       }void EnQueue(LinkQueue &Q,QElemType e)  //{   QueuePtr p;   if(!(p=(QueuePtr)malloc(sizeof(QNode))))     exit(OVERFLOW);     p->data=e;     p->next=NULL;     Q.rear->next=p;     Q.rear=p;     }Status DeQueue(LinkQueue &Q,QElemType &e){   QueuePtr p;   if(Q.front==Q.rear)     return 0;     p=Q.front->next;     e=p->data;     Q.front->next=p->next;     if(Q.rear==p)       Q.rear=Q.front;     free(p);     return 1;       }void QueueTraverse(LinkQueue Q,void(*vi)(QElemType)){   QueuePtr p;   p=Q.front->next;   while(p)   {      vi(p->data);      p=p->next;                  }    printf("\n");    }void BFSTraverse(ALGraph G)// 广度优先遍历 {   int v,u,w;   LinkQueue Q;   for(v=0;v<=G.vexnum;++v)   visited[v]=0;   InitQueue(Q);   for(v=0;v<G.vexnum;v++)/*****v是从0开始循环*****/     if(!visited[v])     {        visited[v]=1;        printf("%d ",G.vertices[v].data);        EnQueue(Q,v);        while(!QueueEmpty(Q))        {           DeQueue(Q,u);           for(w=FirstAdjVex(G,G.vertices[u].data);w>=1;w=NextAdjVex(G,G.vertices[u].data,G.vertices[w].data))              if(!visited[w])             {                visited[w]=1;                printf("%d ",G.vertices[w].data);                EnQueue(Q,w);                            }                            }                  }      printf("\n");    }void TopologicalSort(ALGraph G){int i,k,count;    //ElemType e;    int e;    ArcNode *p;LinkQueue Q; /*定义队列*/InitQueue(Q);for(i=0; i<G.vexnum; i++) //零入度队列  if(!G.vertices[i].indegree) EnQueue(Q,i);  count=0; while(!QueueEmpty(Q)){DeQueue(Q,e); //先将入度为零输出printf("%d  ",G.vertices[e].data);count++; //对输出的顶点计数for(p=G.vertices[e].firstarc;p;p=p->nextarc) //遍历当前邻接点{k=p->adjvex; //邻接点位置if(!(--G.vertices[k].indegree)) //每个邻接点入度减1后若为零则入队列EnQueue(Q,k);}}printf("\n");if(count<G.vexnum){printf("\n该有向图有回路,无法完成拓扑排序!\n"); }}ALGraph G;int main() {  // ALGraph G;   CreateGraph(G);   PrintGraph(G);   printf("图的深度优先遍历的序列为:");     DFSTraverse(G);   printf("图的广度优先遍历的序列为:");   BFSTraverse(G);   printf("图的拓补排序为:");    TopologicalSort(G);   while(1);   return 0;}

0 0