图的遍历

来源:互联网 发布:考研有多难放弃知乎 编辑:程序博客网 时间:2024/06/16 01:07
/*********************************************/
/*    图的遍历    */
/*********************************************/


#include <stdio.h>
#include <stdlib.h>
#include <queue>
using namespace std;
#define M 20
int visited[M]; /*预定义图的最大顶点数*/
typedef char DataType;  /*顶点信息数据类型*/
typedef struct node{    /*边表结点*/
   int adjvex;                  /*邻接点*/
   struct node *next;
}EdgeNode;


typedef struct vnode{   /*头结点类型*/
   DataType vertex;         /*顶点信息*/
   EdgeNode *FirstEdge; /*邻接链表头指针*/




}VertexNode;


typedef struct{           /*邻接表类型*/
 VertexNode adjlist[M];  /*存放头结点的顺序表*/
 int n,e;                 /*图的顶点数与边数*/
}LinkedGraph;




/*函数功能:建立图的邻接表
  函数参数:邻接表指针变量g;存放图信息的文件名filename;图的类型参数c,c=0表示建立无向图,否则表示建立有向图 
  函数返回值:无
*/ 
void creat(LinkedGraph *g,char *filename,int c)
    { int i,j,k;
      EdgeNode *s;
      FILE *fp;
      fp=fopen(filename,"r");
      if (fp)
      {
      fscanf(fp,"%d%d",&g->n,&g->e);              /*读入顶点数与边数*/
    
      for(i=0;i<g->n;i++)
       {
            fscanf(fp,"%1s",&g->adjlist[i].vertex);    /*读入顶点信息*/
            g->adjlist[i].FirstEdge=NULL;         /*边表置为空表*/
       }
  
      for(k=0;k<g->e;k++)                     /*循环e次建立边表*/
        {
            fscanf(fp,"%d%d",&i,&j);                 /*输入无序对(i,j)*/
            s=(EdgeNode *)malloc(sizeof(EdgeNode));
            s->adjvex=j;                         /*邻接点序号为j*/
            s->next=g->adjlist[i].FirstEdge;
            g->adjlist[i].FirstEdge=s;           /*将新结点*s插入顶点vi的边表头部*/
            if (c==0)                            /*无向图*/ 
            {
            s=(EdgeNode *)malloc(sizeof(EdgeNode));
            s->adjvex=i;                         /*邻接点序号为i*/
            s->next=g->adjlist[j].FirstEdge;
            g->adjlist[j].FirstEdge=s;           /*将新结点*s插入顶点vj的边表头部*/
}
        }
    fclose(fp);
    }
    else
    g->n=0;
   }


/*请将本函数补充完整,并进行测试*/


void dfs(LinkedGraph g,int i)
{   /*从顶点i开始深度优先遍历图的连通分量*/
    EdgeNode *p;
  printf("visit vertex: %c \n",g.adjlist[i].vertex);/*访问顶点i*/
  visited[i]=1;
  p=g.adjlist[i].FirstEdge;
  while (p)                 /*从p的邻接点出发进行深度优先搜索*/
    {
        if (!visited[p->adjvex]) dfs(g,p->adjvex);
else p=p->next;
    }
}
/*函数功能:深度优先遍历图
  函数参数:图的邻接表g
*/
void DfsTraverse(LinkedGraph g)
{  int i;
   for (i=0;i<g.n;i++)
       visited[i]=0;     /*初始化标志数组*/
   for (i=0;i<g.n;i++)
       if (!visited[i])  /*vi未访问过*/
            dfs(g,i);
 }




void bfs(LinkedGraph g, int i)
{ /*从顶点i出发广度优先变量图g的连通分量*/


  queue <int> Q; EdgeNode *p;
  printf("visit vertex: %d \n",i);/*访问顶点i*/
  Q.push(i); visited[i]=1;int j;
  while (!Q.empty())
  { j=Q.front();
    Q.pop();
    p=g.adjlist[j].FirstEdge;
    while  (p)

if (!visited[p->adjvex])  {visited[p->adjvex]=1;printf("visit vertex: %d \n",p->adjvex);Q.push(p->adjvex);} 
    p=p->next;
}


  }


}




/*函数功能:广度优先遍历图g
  函数参数:邻接表g
*/
int BfsTraverse(LinkedGraph g)
{  int i,count=0;
   for (i=0;i<g.n;i++)
       visited[i]=0;     /*初始化标志数组*/


   for (i=0;i<g.n;i++)
       if (!visited[i])  /*vi未访问过*/
       {printf("\n");
        count++;            /*连通分量个数加1*/
        bfs(g,i);
       }
   return count;
 }




/*---函数print():输出邻接表存储结构---*/
void print(LinkedGraph  g)
{  EdgeNode *p;
   int i;
   for (i=0;i<g.n;i++)
    {   printf("%c",g.adjlist[i].vertex);
        p=g.adjlist[i].FirstEdge;
        while (p)
        {   printf("-->%d",p->adjvex);
            p=p->next;
        }
     printf("\n");
   }
}
int main()
{ LinkedGraph g;
  creat(&g,"g11.txt",0);  /*已知g11.txt中存储了图的信息*/
  printf("\n The graph is:\n");
  print(g);
  printf("\n");
  DfsTraverse(g);
  printf("\n");
  BfsTraverse(g);
  printf("\n");
  return 0;
}
原创粉丝点击