58-非連通圖的遍歷測試程式碼
阿新 • • 發佈:2019-02-10
非連通圖的遍歷測試程式碼:
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define MAXV 8
#define N 8
typedef struct ANode
{
int adjvex; //記錄某頂點的鄰接點
struct ANode *nextarc; //指向下一條邊節點的指標
} ArcNode; //邊節點型別
typedef int Vertex;
typedef struct Vnode
{
Vertex data; //儲存頂點的資訊
ArcNode *firstarc; //指向第一個邊節點
} VNode; //表頭節點型別
typedef VNode AdjList[MAXV];
typedef struct
{
AdjList adjlist; //鄰接表,這其實是一個數組(順序表)
int n,e; //記錄頂點個數n,邊數e
} ALGraph; //完整的圖鄰接表型別
//圖的定義:鄰接矩陣
typedef struct MGRAPH{
int n; //頂點數
int e; //邊數
int deges[MAXV][MAXV]; //鄰接矩陣
} MGraph;
/*
將鄰接矩陣轉換成鄰接表
MGraph *g:表示鄰接矩陣
*/
ALGraph *MatToList(MGraph *g)
{
int i;
int j;
ArcNode *p = NULL;
ALGraph *G = (ALGraph *)malloc(sizeof(ALGraph));
//給所有頭節點的指標域置初值
for(i = 0; i < g->n; i++)
{
G->adjlist[i].firstarc = NULL;
}
//根據鄰接矩陣建立鄰接表中節點
for(i = 0; i < g->n; i++)
{
for(j = g->n - 1; j >= 0; j--)
{
if(g->deges[i][j] != 0)
{
p = (ArcNode *)malloc(sizeof(ArcNode));
p->adjvex = j;
//採用頭插法,插入鄰接表
p->nextarc = G->adjlist[i].firstarc;
G->adjlist[i].firstarc = p;
}
}
}
G->n = g->n;
G->e = g->e;
return G;
}
//定義陣列,演算法執行前全置0
int visited[N] = {0};
void init_visited(int *arr)
{
int i;
if(arr == NULL)
{
return;
}
for(i = 0; i < N; i++)
{
*(arr + i) = 0;
}
}
//G表示給定的圖,採用鄰接表儲存
//v表示起始點
void DFS(ALGraph *G , int v)
{
ArcNode *p = NULL;
int w;
if(G == NULL)
{
return;
}
//置為已訪問標記
visited[v] = 1;
//輸出被訪問頂點的編號
printf("%d\t" , v);
//p指向頂點v的第一條邊的頭節點
p = G->adjlist[v].firstarc;
while(p != NULL)
{
//如果頂點w沒有被訪問過,則遞迴訪問
w = p->adjvex;
if(visited[w] == 0)
{
DFS(G,w);
}
//如果已經訪問過,p則指向下一條邊的頭節點
p = p->nextarc;
}
}
//G表示給定的圖,採用鄰接表儲存
//v表示起始點
void BFS(ALGraph *G , int v)
{
ArcNode *p;
int w;
int queue[MAXV],front=0,rear=0;
//訪問第一個頂點併入隊,注意這裡是採用的環形佇列
printf("%d\t",v);
//標記為已訪問
visited[v]=1;
rear=(rear+1)%MAXV;
queue[rear]=v;
//佇列是否為空,否則取出隊中未被訪問的頂點
while (front!=rear)
{
//取出隊中頂點
front=(front+1)%MAXV;
w=queue[front];
//獲取鄰接點(訪問該頂點的所有未訪問的鄰接點並使之入隊)
p=G->adjlist[w].firstarc;
while (p!=NULL)
{
//這個鄰接點是否已經訪問
if (visited[p->adjvex]==0)
{
//訪問這個鄰接點,並將該鄰接點標記為已訪問
printf( "%d\t",p->adjvex);
visited[p->adjvex]=1;
//然後將鄰接點入隊
rear=(rear+1)%MAXV;
queue[rear]=p->adjvex;
}
//獲取下一個鄰接點
p=p->nextarc;
}
}
}
//採用深度優先搜尋遍歷非連通無向圖
void DFS1(ALGraph *G)
{
int i;
for (i=0;i<G->n;i++)
{
if (visited[i]==0)
{
DFS(G , i);
}
}
}
//採用廣度優先搜尋遍歷非連通無向圖
void BFS1(ALGraph *G)
{
int i;
for (i=0;i<G->n;i++)
{
if (visited[i]==0)
{
BFS(G , i);
}
}
}
//判斷是否是連通圖
int Connect(ALGraph *G)
{
int i;
//設定預設值
int flag=1;
//初始化visited陣列
for (i=0; i<G->n; i++)
visited[i]=0;
//這裡以深度優先搜尋為例 , 以頂點0為起始點開始遍歷
DFS(G,0);
//判斷所有頂點是否已經被訪問
for (i=0; i<G->n; i++)
//如果有一個頂點沒有被訪問,說明這不是連通圖,則更改flag標誌
if (visited[i]==0)
{
flag=0;
break;
}
return flag;
}
int main(void)
{
int i;
int j;
//result預設值為1,是連通圖
int result = 1;
//A是一個非連通圖
int A[8][8]=
{
{0,1,0,1,0,0,0,0},
{1,0,1,0,0,0,0,0},
{0,1,0,1,1,0,0,0},
{1,0,1,0,1,0,0,0},
{0,0,1,1,0,0,0,0},
{0,0,0,0,0,0,1,0},
{0,0,0,0,0,1,0,1},
{0,0,0,0,0,0,1,0},
};
ALGraph *ag = NULL;
MGraph mg;
mg.n = 8;
mg.e = 9;
for(i = 0; i < MAXV; i++)
{
for(j = 0; j < MAXV; j++)
{
mg.deges[i][j] = A[i][j];
}
}
ag = MatToList(&mg);
printf("\n");
printf("深度優先搜尋遍歷非連通圖:");
//採用深度優先搜尋遍歷非連通無向圖
DFS1(ag);
printf("\n\n");
//在呼叫BFS1之前,先把visited陣列初始化
init_visited(visited);
printf("廣度優先搜尋遍歷非連通圖:");
//採用廣度優先搜尋遍歷非連通無向圖
BFS1(ag);
printf("\n\n");
init_visited(visited);
result = Connect(ag);
printf("\n\n");
if(result == 1)
{
printf("是連通圖\n");
}
else
{
printf("非連通圖\n");
}
return 0;
}
測試結果: