最近在學圖,寫個筆記。
圖的創建一般有鄰接矩陣和鄰接表兩種方法,鄰接矩陣對於邊數相對於頂點較少的圖會有極大的浪費,所以用鄰接表,用數組與鏈表相配合
頂點用一維數組儲存
所有頂點的鄰接點構成一個線性表,因爲鄰接點的個數不確定,所以用單鏈表
圖的深度優先搜索是對先序遍歷的推廣 一個遞歸的過程,沿着一個方向遍歷,一直到最後,然後再回來到另一個結點沿着一個方向。
廣度優先遍歷就是一層一層的遍歷。如上圖
上代碼:
#include<stdio.h>
#include<stdlib.h>
#define MAXVEX 7 //代表最大頂點數
#define INFINITY 65535 //代表無窮大
typedef struct GraphNode
{
int index; //下標
struct GraphNode *next; //指向下一個的指針
}GraphNode;
typedef struct Gra
{
char c; //頂點元素
GraphNode *first ;
}Gra;
typedef struct Graph
{
Gra vex[MAXVEX];
int numvex,edge; //頂點元素和邊的數量
}Graph;
//創建一個隊列,用來廣度優先遍歷
typedef struct QNode
{
int data;
struct QNode *next;
}QNode,*Queueprt;
typedef struct
{
Queueprt front,rear;
}LinkQueue;
//隊列的初始化
void InitQueue(LinkQueue *q)
{
q->front=q->rear=(Queueprt)malloc(sizeof(QNode));
q->front->next=NULL;
}
//入隊列
void EnQueue(LinkQueue *q,int e)
{
Queueprt p;
p=(Queueprt)malloc(sizeof(QNode));
p->data=e;
q->rear->next=p;
p->next=NULL;
q->rear=p;
}
//出隊列
void DeQueue(LinkQueue *q,int *e)
{
if(q->front==q->rear)
{
return;
}
Queueprt p;
p=q->front->next;
*e = p->data;
q->front->next=p->next;
if(p==q->rear)
{
q->rear=q->front;
}
free(p);
}
//判斷隊列是否爲空
int QueueEmpty(LinkQueue *q)
{
if(q->front==q->rear)
{
return 1;
}
else
{
return 0;
}
}
//創建圖
void create(Graph *g)
{
int i,j,m,n;
GraphNode *p,*q;
printf("輸入頂點元素的數量和邊的數量:\n");
scanf("%d %d",&(g->numvex),&(g->edge));
printf("輸入頂點元素:\n");
for(i=0;i<g->numvex;i++)
{
getchar();
scanf("%c",&(g->vex[i].c) );
g->vex[i].first=NULL;
}
//建立邊集
printf("輸入邊兩邊頂點的下標:\n");
for(j=0;j<g->edge;j++)
{
scanf("%d %d",&m,&n);
p=(GraphNode *)malloc(sizeof(GraphNode));
p->index=m;
p->next=g->vex[n].first;
g->vex[n].first=p; //這裏是把first移到p
q=(GraphNode *)malloc(sizeof(GraphNode));
q->index=n;
q->next=g->vex[m].first;
g->vex[m].first=q;
}
}
void print(Graph *g)
{
int i;
GraphNode *p;
for(i=0;i<g->numvex;i++)
{
p=g->vex[i].first;
while(p)
{
printf("(%c,%c)",g->vex[i].c,g->vex[p->index].c);
p=p->next;
}
printf("\n");
}
}
//DFS遍歷
void DFS(Graph *g,int i,int *visited)
{
GraphNode *p;
visited[i]=1;
printf("%c ",g->vex[i].c);
p=g->vex[i].first;
while( p )
{
if(!visited[p->index])
{
DFS(g,p->index,visited);
}
p=p->next;
}
}
void TraDFS(Graph *g)
{
int i;
int visited[MAXVEX];
for(i=0;i<MAXVEX;i++)
{
visited[i]=0;
}
for(i=0;i<g->numvex;i++)
{
if(!visited[i])
{
DFS(g,i,visited);
}
}
}
//BFS遍歷
void TraBFS(Graph *g)
{
int i,j;
LinkQueue q;
int visited[MAXVEX];
for(i=0;i<MAXVEX;i++)
{
visited[i]=0;
}
InitQueue(&q);
for(i=0;i<g->numvex;i++)
{
if(!visited[i])
{
printf("%c ",g->vex[i].c);
visited[i]=1;
EnQueue(&q, i);
while(!QueueEmpty(&q))
{
DeQueue(&q,&i);
GraphNode *p = g->vex[i].first;
while( p )
{
if(!visited[p->index])
{
printf("%c ",g->vex[p->index].c);
visited[p->index]=1;
EnQueue(&q,p->index);
}
p=p->next;
}
}
}
}
}
int main(){
Graph g;
create(&g);
print(&g);
printf("DFS遍歷結果:\n");
TraDFS(&g);
printf("\nBFS遍歷結果爲:\n");
TraBFS(&g);
printf("\n");
return 0;
}
一開始出隊列寫錯了,廣度遍歷不對,找了好久的原因。