1. 程式人生 > 其它 >C語言 圖的遍歷(廣度優先和深度優先、鄰接矩陣)

C語言 圖的遍歷(廣度優先和深度優先、鄰接矩陣)

#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include<stdlib.h>
/*--------輔助廣度優先遍歷用的空閒單元法迴圈佇列-----------*/
#define MaxQueuenNum 20
typedef struct queue
{
    int* array;
    int front;
    int rear;
}Queue;
/*---------------------------------------------------------*/

/*-----------------鄰接矩陣的結構體型別--------------------
*/ typedef char VextexType; typedef int EdgeType; #define MaxNum 15 //鄰接矩陣的最大頂點數 typedef struct adjacency_matrix { VextexType MGVexTexArray[MaxNum]; //頂點表 EdgeType Edge[MaxNum][MaxNum]; int VertexNum, EdgeNum; //頂點數和邊數 }MGraph; /*---------------------------------------------------------*/ /*
鄰接矩陣的建立*/ void Creat_Adjacency_Matrix(MGraph* MG) { int i, j, x, y; //先輸入頂點數和邊數 printf("輸入鄰接矩陣的頂點數和邊數:"); scanf_s("%d %d", &MG->VertexNum, &MG->EdgeNum); //初始化頂點表 printf("輸入鄰接矩陣各個頂點的資訊:"); for (i = 0; i < MG->VertexNum; i++) { getchar(); scanf_s(
"%c", &MG->MGVexTexArray[i]); } //初始化邊表 for (x = 0; x < MG->VertexNum; x++) { for (y = 0; y < MG->VertexNum; y++) { MG->Edge[x][y] = 0; //初始化邊表的各項為0,表示兩者還沒有直達的邊 } } //開始構造鄰接矩陣 for (j = 0; j < MG->EdgeNum; j++) { printf("請輸入邊兩個頂點的下標:"); scanf_s("%d %d", &x, &y); MG->Edge[x][y] = 1; //由於無向網和無向圖是對稱的所以 MG->Edge[y][x] = MG->Edge[x][y]; } printf("\n臨接矩陣輸出如下:\n"); for (x = 0; x < MG->VertexNum; x++) { for (y = 0; y < MG->VertexNum; y++) { printf("%d ", MG->Edge[x][y]); } printf("\n"); } } int visited[20];//全域性變數標記陣列,用於記錄頂點有沒有被訪問過,訪問過記為1反之為0 //由於C沒有bool或者boolean,所以用0表示False,1表示True //深度優先演算法遍歷鄰接矩陣 void DFS_MG(MGraph* MG, int i) { int k; visited[i] = 1; printf("%c ", MG->MGVexTexArray[i]); for (k = 0; k < MG->VertexNum; k++) { if (MG->Edge[i][k] == 1 && !visited[k]) { DFS_MG(MG, k); } } } void DFS_Traverse_MG(MGraph* MG) { int i; //初始化標誌陣列 for (i = 0; i < MG->VertexNum; i++) { visited[i] = 0; } //開始深度優先遍歷 for (i = 0; i < MG->VertexNum; i++) { if (!visited[i]) { DFS_MG(MG, i); } } } //空閒單元法建立迴圈佇列 void CreatQueue(Queue* queue) { queue->array = (int*)malloc(sizeof(int) * MaxQueuenNum); queue->front = 0; queue->rear = 0; } //入隊 void EnQueue(Queue* queue, int EnElem) { if ((queue->rear + 1) % MaxQueuenNum == queue->front) { printf("無法入隊,佇列滿"); return; } queue->array[queue->rear] = EnElem; queue->rear = (queue->rear + 1) % MaxQueuenNum; } //出隊 int DeQueue(Queue* queue) { int temp; if (queue->rear == queue->front) { printf("佇列為空,沒有元素可以出隊"); return 0; } temp = queue->array[queue->front]; queue->front = (queue->front + 1) % MaxQueuenNum; return temp; } //判斷佇列是否為空,空就賦1表示為空,反之為0 int Queue_isEmpty(Queue* queue) { if (queue->rear == queue->front) { return 1; } return 0; } //廣度優先演算法遍歷鄰接矩陣 void BFS_Traverse_MG(MGraph* MG) { int i, j; Queue q; CreatQueue(&q); //初始化標誌陣列 for (i = 0; i < MG->VertexNum; i++) visited[i] = 0; //開始構建廣度優先演算法遍歷 for (i = 0; i < MG->VertexNum; i++)//若是連通圖只執行一次即可遍歷完 { if (!visited[i]) { EnQueue(&q, i); visited[i] = 1; while (!Queue_isEmpty(&q)) //隊不為空 { i = DeQueue(&q); printf("%c ", MG->MGVexTexArray[i]); for (j = 0; j < MG->VertexNum; j++) { if (!visited[j] && MG->Edge[i][j] == 1) { visited[j] = 1; EnQueue(&q, j); } } } } } } int main() { int i; MGraph* MG = (MGraph*)malloc(sizeof(MGraph)); printf("-----輸入每個數都是用空格隔開------\n"); Creat_Adjacency_Matrix(MG); printf("--------------------------------------------\n"); printf("\n鄰接矩陣的深度遍歷:"); DFS_Traverse_MG(MG); printf("\n"); printf("鄰接矩陣的廣度遍歷:"); BFS_Traverse_MG(MG); printf("\n"); printf("\n--------------------------------------------\n"); printf("\n"); free(MG); system("pause"); return 0; }