1. 程式人生 > >C語言之圖的建立 dfs bfs操作

C語言之圖的建立 dfs bfs操作

一、實驗目的

1、掌握圖的鄰接矩陣和鄰接表儲存結構;

2、掌握圖的廣度優先遍歷和深度優先遍歷演算法。

二、實驗環境

PC微機,WindowsVisual C++

三、實驗內容

1、圖的鄰接矩陣和鄰接表儲存。

1)基本要求

利用圖的鄰接矩陣和鄰接表,編寫圖的建立、顯示演算法。圖的結構如圖1所示:

1 具有10個頂點的圖



3)演算法實現


鄰接矩陣


標頭檔案

#define MaxVex 100

typedef int  VertexType; 

typedef int    

EdgeType;

typedef struct  graph

{    

       int vnum, ednum;                                                 //頂點的個數,邊的個數

       VertexTypevexs[MaxVex];                                 //用來存頂點資料

       EdgeType   edges[MaxVex][MaxVex];               //用來存邊的資料(兩點代替一邊)

} Mgraph;

 

 

主檔案

#include <stdio.h>

#include <stdlib.h>

//#include <string.h>

//#include <malloc.h>

#include "list.h"

 

 

Mgraph *creatMgraph()                                                //建立圖

{

       Mgraph*p;

       inti,j,k;

       p=(Mgraph*)malloc(sizeof(Mgraph));

 

       printf("請輸出頂點和邊的個數\n");

       scanf("%d%d",&p->vnum,&p->ednum);

 

       for(i=0;i<p->vnum;i++)                                                         //矩陣初始化

       {

              for(j=0;j<p->vnum;j++)

              {

                     p->edges[i][j]=0;

              }

       }

 

       printf("輸入頂點的資訊\n");

       for(i=0;i<p->vnum;i++)

       {

              scanf("%d",&p->vexs[i]);

       }

       printf("輸入邊的資訊\n");

       {

              for(k=0;k<p->ednum;k++)

              {

                     scanf("%d%d",&i,&j);

                     p->edges[i][j]=1;                                            //無向圖的建立

                     p->edges[j][i]=1;

              }

       }

       returnp;

}

 

void displayGraph(Mgraph *mG)                                //輸出圖的資訊

{

       inti,j;

       printf("請輸入點的資訊\n");

       for(i=0;i<mG->vnum;i++)

       {

              printf("%d\t",mG->vexs[i]);

       }

       printf("請輸入邊的資訊\n");

       for(i=0;i<mG->vnum;i++)

       {

              for(j=0;j<mG->vnum;j++)

              {

                     if(mG->edges[i][j]==1)

                     {

                            printf("%d%d ",i,j);

                     }

              }

       }

}

 

void main()

{

       Mgraph*M;

       M=creatMgraph();

       displayGraph(M);

}

鄰接表

#include <stdio.h>

#include <stdlib.h>

//#include <string.h>

//#include <malloc.h>

#include "graph.h"

 

標頭檔案

typedef struct anode

{

       intadjvex;

       structanode *next;

}Anode;

 

typedef struct vnode

{

       intvertex;

       Anode*first;

}Vnode;

 

typedef struct

{

       Vnodevex[MaxVex];

       intvnum;

       intednum;

}Lgraph;

 


#include <stdio.h>

#include <stdlib.h>

//#include <string.h>

//#include <malloc.h>

#include "graph.h"

 

 

Lgraph * createGraph()                                        //建立圖

{

       Lgraph*p;

       Anode*s;

       inti,j,k;

       p=(Lgraph*)malloc(sizeof(Lgraph));

       printf("請輸入頂點和邊的個數\n");

       scanf("%d%d",&p->vnum,&p->ednum);

       printf("請輸入頂點的資訊\n");

       for(i=0;i<p->vnum;i++)

       {

              scanf("%d",&p->vex[i].vertex);

              s=(Anode*)malloc(sizeof(Anode));

              p->vex[i].first=s;

              s->adjvex=NULL;

              s->next=NULL;

       }

       printf("請輸入邊的資訊\n");

       for(k=0;k<p->ednum;k++)

       {

              scanf("%d%d",&i,&j);

              s=(Anode*)malloc(sizeof(Anode));

              s->adjvex=j;

              s->next=p->vex[i].first->next;

              p->vex[i].first->next=s;

             

              s=(Anode*)malloc(sizeof(Anode));

              s->adjvex=i;

              s->next=p->vex[j].first->next;

              p->vex[j].first->next=s;

       }

       returnp;

}

void display(Lgraph *p)                                    //輸出圖的資訊

{

       inti;

       Anode*current;

       printf("輸出圖的頂點的資訊\n");

       for(i=0;i<p->vnum;i++)

       {

              printf("%d\t",p->vex[i].vertex);

       }

       printf("輸出圖的邊的資訊\n");

       for(i=0;i<p->vnum;i++)

       {

              current=p->vex[i].first->next;

              while(current!=NULL)

              {

                     printf("%d",p->vex[i].vertex);

                     printf("%d\t",current->adjvex);

                     current=current->next;

              }

       }

}

void main()

{

       Lgraph*G;

       G=createGraph();

       display(G);

}

2、基於圖的鄰接表結構,程式設計實現圖的廣度優先遍歷和深度優先遍歷演算法。

1)基本要求

利用佇列,程式設計實現BFS演算法, 列印訪問頂點序列。利用遞迴,實現DFS,列印訪問頂點序列。遍歷演算法的源點提示使用者鍵盤輸入。

3)演算法實現

此處採用鄰接表

標頭檔案

typedef struct anode

{

       intadjvex;

       structanode *next;

}Anode;

 

typedef struct vnode

{

       intvertex;

       Anode*first;

}Vnode;

 

typedef struct

{

       Vnodevex[MaxVex];

       intvnum;

       intednum;

       intvisited[MaxVex];

}Lgraph;

typedef struct node queue                                        //新增一個佇列結構體,bfs需要

{

Anode *first;

Anode *rear;

}Queue;

 

#include <stdio.h>

#include <stdlib.h>

//#include <string.h>

//#include <malloc.h>

#include "graph.h"

 

 

Lgraph *createGraph()

{

       Lgraph *p;

       Anode *s;

       int i,j,k;

       p=(Lgraph*)malloc(sizeof(Lgraph));

       printf("請輸入頂點和邊的個數\n");

       scanf("%d%d",&p->vnum,&p->ednum);

       printf("請輸入頂點的資訊\n");

       for(i=0;i<p->vnum;i++)

       {

              scanf("%d",&p->vex[i].vertex);

              s=(Anode*)malloc(sizeof(Anode));

              p->vex[i].first=s;

              s->adjvex=NULL;

              s->next=NULL;

       }

       printf("請輸入邊的資訊\n");

       for(k=0;k<p->ednum;k++)

       {

              scanf("%d%d",&i,&j);

              s=(Anode*)malloc(sizeof(Anode));

              s->adjvex=j;

              s->next=p->vex[i].first->next;

              p->vex[i].first->next=s;

             

              s=(Anode*)malloc(sizeof(Anode));

              s->adjvex=i;

              s->next=p->vex[j].first->next;

              p->vex[j].first->next=s;

       }

       return p;

}

void display(Lgraph *p)

{

       int i;

       Anode *current;

       printf("輸出圖的頂點的資訊\n");

       for(i=0;i<p->vnum;i++)

       {

              printf("%d\t",p->vex[i].vertex);

       }

       printf("輸出圖的邊的資訊\n");

       for(i=0;i<p->vnum;i++)

       {

              current=p->vex[i].first->next;

              while(current!=NULL)

              {

                     printf("%d",p->vex[i].vertex);

                     printf("%d\t",current->adjvex);

                     current=current->next;

              }

       }

}

Queue *Initiate_queue()                                                                     //初始化佇列

{

       Queue *Q;

       Anode *s;

       Q=(Queue*)malloc(sizeof(Queue));

       s=(Anode *)malloc(sizeof(Anode));

       s->adjvex=NULL;

       s->next=NULL;

       Q->first=Q->rear=s;   

       return Q;

}

int De_queue(Queue *q)                                                       //刪除佇列元素

{     

       Anode *t;

       Anode *p=q->first;

       int u;

       if(q->first==q->rear)

       {

              printf("佇列為空\n");

       }

       else

       {

              t=q->first->next;

              q->first->next=t->next;

              u=t->adjvex;

              free(t);

              while(p->next!=NULL)

              {

                     p=p->next;

              }

              q->rear=p;

       }

       return u;

}

void En_queue(Queue *q,int source)                              //source入佇列q

{

       Anode *s;

       s=(Anode*)malloc(sizeof(Anode));

       s->adjvex=source;

       s->next=NULL;

       if(q->first==q->rear)

       {

              q->first->next=s;

       }

       else

       {

              q->rear->next=s;

       }

       q->rear=s;

}

int Isempty(Queue *q)                                                                //看佇列是否為空

{

       if(q->first==q->rear)

       {

              return 0;

       }

       else

       {

              return 1;

       }

 

}

void BFS(Lgraph *p,Queue *q,int source)                                   //要完成BFS演算法,需要佇列中的建立 增加刪除操作

{

       Anode *current;

       int i,u;

       int visited[MaxVex];

       for(i=0;i<p->vnum;i++)

       {

              visited[i]=0;                                                        //設定一個標誌陣列用來bfs

       }

       printf("The BFSList\n");

       printf("%d",p->vex[source].vertex);

       visited[source]=1;

       En_queue(q,source);

       while(Isempty(q))

       {

              u=De_queue(q);

              current=p->vex[u].first->next;

              while(current!=NULL)

              {

                     if(visited[current->adjvex]==0)

                     {

                            printf("%d",current->adjvex);

                            visited[current->adjvex]=1;

                            En_queue(q,current->adjvex);

                            current=current->next;

                     }

                     else

                     {

                            current=current->next;

                     }

              }

       }

}

void Initvisited(Lgraph *p)                                                                //設定一個存在結構體內的標誌陣列,結構體內陣列可傳入函式

{

       int i;

       for(i=0;i<p->vnum;i++)

       {

              p->visited[i]=0;                                                                         //為0代表未用過,用過修改為1

       }

}

void DFS(Lgraph *p,int source)                                                            

{

       Anode *current;

       printf("%d",p->vex[source].vertex);

       p->visited[source]=1;

       current=p->vex[source].first->next;

       while(current!=NULL)

       {

              if(p->visited[current->adjvex]==0)

              {

                     DFS(p,current->adjvex);

              }