1. 程式人生 > >03鄰接矩陣的深度和廣度遍歷的C語言實現

03鄰接矩陣的深度和廣度遍歷的C語言實現

返回 算法 ++ 其它 連通圖 edge main fin site

#include "stdio.h"
#include "stdlib.h"
#include "io.h"
#include "math.h"
#include "time.h"

#define OK 1
#define ERROR 0
#define TRUE 1
#define FALSE 0

typedef int Status; /* Status是函數的類型,其值是函數結果狀態代碼,如OK等 */
typedef int Boolean; /* Boolean是布爾類型,其值是TRUE或FALSE */

typedef char VertexType; /* 頂點類型應由用戶定義 */
typedef int EdgeType; /* 邊上的權值類型應由用戶定義 */

#define MAXSIZE 9 /* 存儲空間初始分配量 */
#define MAXEDGE 15
#define MAXVEX 9
#define INFINITY 65535

typedef struct
{
VertexType vexs[MAXVEX]; /* 頂點表 */
EdgeType arc[MAXVEX][MAXVEX];/* 鄰接矩陣,可看作邊表 */
int numVertexes, numEdges; /* 圖中當前的頂點數和邊數 */
}MGraph;

/* 用到的隊列結構與函數********************************** */

/* 循環隊列的順序存儲結構 */
typedef struct
{
int data[MAXSIZE];
int front; /* 頭指針 */
int rear; /* 尾指針,若隊列不空,指向隊列尾元素的下一個位置 */
}Queue;

/* 初始化一個空隊列Q */
Status InitQueue(Queue *Q)
{
Q->front=0;
Q->rear=0;
return OK;
}

/* 若隊列Q為空隊列,則返回TRUE,否則返回FALSE */
Status QueueEmpty(Queue Q)
{
if(Q.front==Q.rear) /* 隊列空的標誌 */
return TRUE;
else
return FALSE;
}

/* 若隊列未滿,則插入元素e為Q新的隊尾元素 */
Status EnQueue(Queue *Q,int e)
{
if ((Q->rear+1)%MAXSIZE == Q->front) /* 隊列滿的判斷 */
return ERROR;
Q->data[Q->rear]=e; /* 將元素e賦值給隊尾 */
Q->rear=(Q->rear+1)%MAXSIZE;/* rear指針向後移一位置, */
/* 若到最後則轉到數組頭部 */
return OK;
}

/* 若隊列不空,則刪除Q中隊頭元素,用e返回其值 */
Status DeQueue(Queue *Q,int *e)
{
if (Q->front == Q->rear) /* 隊列空的判斷 */
return ERROR;
*e=Q->data[Q->front]; /* 將隊頭元素賦值給e */
Q->front=(Q->front+1)%MAXSIZE; /* front指針向後移一位置, */
/* 若到最後則轉到數組頭部 */
return OK;
}
/* ****************************************************** */


void CreateMGraph(MGraph *G)
{
int i, j;

G->numEdges=15;
G->numVertexes=9;

/* 讀入頂點信息,建立頂點表 */
G->vexs[0]=‘A‘;
G->vexs[1]=‘B‘;
G->vexs[2]=‘C‘;
G->vexs[3]=‘D‘;
G->vexs[4]=‘E‘;
G->vexs[5]=‘F‘;
G->vexs[6]=‘G‘;
G->vexs[7]=‘H‘;
G->vexs[8]=‘I‘;


for (i = 0; i < G->numVertexes; i++)/* 初始化圖 */
{
for ( j = 0; j < G->numVertexes; j++)
{
G->arc[i][j]=0;
}
}

G->arc[0][1]=1;
G->arc[0][5]=1;

G->arc[1][2]=1;
G->arc[1][8]=1;
G->arc[1][6]=1;

G->arc[2][3]=1;
G->arc[2][8]=1;

G->arc[3][4]=1;
G->arc[3][7]=1;
G->arc[3][6]=1;
G->arc[3][8]=1;

G->arc[4][5]=1;
G->arc[4][7]=1;

G->arc[5][6]=1;

G->arc[6][7]=1;


for(i = 0; i < G->numVertexes; i++)
{
for(j = i; j < G->numVertexes; j++)
{
G->arc[j][i] =G->arc[i][j];
}
}

}

Boolean visited[MAXVEX]; /* 訪問標誌的數組 */

/* 鄰接矩陣的深度優先遞歸算法 */
void DFS(MGraph G, int i)
{
int j;
visited[i] = TRUE;
printf("%c ", G.vexs[i]);/* 打印頂點,也可以其它操作 */
for(j = 0; j < G.numVertexes; j++)
if(G.arc[i][j] == 1 && !visited[j])
DFS(G, j);/* 對為訪問的鄰接頂點遞歸調用 */
}

/* 鄰接矩陣的深度遍歷操作 */
void DFSTraverse(MGraph G)
{
int i;
for(i = 0; i < G.numVertexes; i++)
visited[i] = FALSE; /* 初始所有頂點狀態都是未訪問過狀態 */
for(i = 0; i < G.numVertexes; i++)
if(!visited[i]) /* 對未訪問過的頂點調用DFS,若是連通圖,只會執行一次 */
DFS(G, i);
}

/* 鄰接矩陣的廣度遍歷算法 */
void BFSTraverse(MGraph G)
{
int i, j;
Queue Q;
for(i = 0; i < G.numVertexes; i++)
visited[i] = FALSE;
InitQueue(&Q); /* 初始化一輔助用的隊列 */
for(i = 0; i < G.numVertexes; i++) /* 對每一個頂點做循環 */
{
if (!visited[i]) /* 若是未訪問過就處理 */
{
visited[i]=TRUE; /* 設置當前頂點訪問過 */
printf("%c ", G.vexs[i]);/* 打印頂點,也可以其它操作 */
EnQueue(&Q,i); /* 將此頂點入隊列 */
while(!QueueEmpty(Q)) /* 若當前隊列不為空 */
{
DeQueue(&Q,&i); /* 將隊對元素出隊列,賦值給i */
for(j=0;j<G.numVertexes;j++)
{
/* 判斷其它頂點若與當前頂點存在邊且未訪問過 */
if(G.arc[i][j] == 1 && !visited[j])
{
visited[j]=TRUE; /* 將找到的此頂點標記為已訪問 */
printf("%c ", G.vexs[j]); /* 打印頂點 */
EnQueue(&Q,j); /* 將找到的此頂點入隊列 */
}
}
}
}
}
}


int main(void)
{
MGraph G;
CreateMGraph(&G);
printf("\n深度遍歷:");
DFSTraverse(G);
printf("\n廣度遍歷:");
BFSTraverse(G);
return 0;
}

03鄰接矩陣的深度和廣度遍歷的C語言實現