1. 程式人生 > >資料結構 實驗八 圖的遍歷

資料結構 實驗八 圖的遍歷

/*********************************************/
/*    圖的遍歷    	 */
/*********************************************/

#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)
{

    EdgeNode *p;
    printf("visit vertex: %c\n",g.adjlist[i].vertex);
    visited[i]=1;
    p=g.adjlist[i].FirstEdge;
    while(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);
 }
/*********************************************/
 queue<int>Q;
void bfs(LinkedGraph g, int i)
{ /*從頂點i出發廣度優先變數圖g的連通分量*/
    EdgeNode *p;
    visited[i]=1;
    printf("%d",i);
    p=g.adjlist[i].FirstEdge;
    while(p)
    {
        if(!visited[i]){
            printf("%d",i);
            Q.push(i);
        }
        p=p->next;
    }
    while(!Q.empty())
    {
        int u=Q.front();
        Q.pop();
        bfs(g,u);
    }
}
/*********************************************/
/*函式功能:廣度優先遍歷圖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;
}