C語言之圖的建立 dfs bfs操作
一、實驗目的
1、掌握圖的鄰接矩陣和鄰接表儲存結構;
2、掌握圖的廣度優先遍歷和深度優先遍歷演算法。
二、實驗環境
PC微機,Windows, Visual C++
三、實驗內容
1、圖的鄰接矩陣和鄰接表儲存。
(1)基本要求
利用圖的鄰接矩陣和鄰接表,編寫圖的建立、顯示演算法。圖的結構如圖1所示:
圖1 具有10個頂點的圖
(3)演算法實現
鄰接矩陣
標頭檔案
#define MaxVex 100
typedef int VertexType;
typedef int
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);
}