/* file name: dfs.c */ /* 圖形的追蹤: 相鄰串列與蹤向優先搜尋法(DFS)*/ #include #include #define MAX_V 100 /*最大節點數*/ #define TRUE 1 #define FALSE 0 /*定義資料結構*/ typedef struct node_tag { int vertex; struct node_tag *link; } Node; Node *adjlist[MAX_V+1]; /*宣告相鄰串列*/ int visited[MAX_V+1]; /*記錄頂點是否已拜訪*/ int total_vertex; void build_adjlist(void); void show_adjlist(void); void show_weight_matrix(void); void dfs(int); Node *searchlast(Node *); int weight_matrix[MAX_V+1][MAX_V+1]; /* 儲存權重矩陣 */ int main() { build_adjlist(); /*以相鄰串列表示圖形*/ show_weight_matrix(); /*顯示權重矩陣*/ show_adjlist(); /*顯示串列之資料*/ puts("\n------Depth Fisrt Search------"); dfs(1); /*圖形之蹤向優先搜尋,以頂點1為啟始頂點*/ printf("\n"); return 0; } void build_adjlist() { FILE *fptr; Node *node, *lastnode; int vi, vj, weight; char line[256]; int line_count = 0; fptr = fopen("down_1.dat", "r"); if (fptr == NULL) { perror("down_1.dat"); exit(0); } // 計算總頂點數 while (fgets(line, sizeof(line), fptr)) { line_count++; } total_vertex = line_count; // 總頂點數等於行數 rewind(fptr); // 初始化陣列及各串列啟始值 for (vi = 1; vi <= total_vertex; vi++) { visited[vi] = FALSE; adjlist[vi] = (Node *)malloc(sizeof(Node)); adjlist[vi]->vertex = vi; adjlist[vi]->link = NULL; } // 讀取下三角矩陣 for (vi = 1; vi <= total_vertex; vi++) { // 只讀取到第vi個元素(下三角部分) for (vj = 1; vj < vi; vj++) { if (fscanf(fptr, "%d", &weight) != 1) { printf("Error reading weight at vi=%d, vj=%d\n", vi, vj); continue; } // 儲存權重到矩陣 weight_matrix[vi][vj] = weight; weight_matrix[vj][vi] = weight; // 因為是無向圖,所以對稱儲存 // 如果相鄰(weight = 1),則建立連結 if (weight == 1) { // 加入 vi -> vj 的連結 node = (Node *)malloc(sizeof(Node)); node->vertex = vj; node->link = NULL; lastnode = searchlast(adjlist[vi]); lastnode->link = node; // 加入 vj -> vi 的連結(因為是無向圖) node = (Node *)malloc(sizeof(Node)); node->vertex = vi; node->link = NULL; lastnode = searchlast(adjlist[vj]); lastnode->link = node; } } // 讀取對角線元素(一定是0) fscanf(fptr, "%d", &weight); } fclose(fptr); } /*顯示各相鄰串列之資料*/ void show_adjlist() { int index; Node *ptr; puts("Head adjacency nodes"); puts("------------------------------"); for (index = 1; index <= total_vertex; index++) { printf("V%-2d ",adjlist[index]->vertex); ptr = adjlist[index]->link; while (ptr != NULL) { printf("--> V%d ",ptr->vertex); ptr = ptr->link; } printf("\n"); } } /* 修改顯示權重矩陣的函數,使其更清晰 */ void show_weight_matrix() { int i, j; printf("\n=== Weight Matrix ===\n"); printf(" "); for(j = 1; j <= total_vertex; j++) { printf("V%-3d", j); } printf("\n"); for(i = 1; i <= total_vertex; i++) { printf("V%-3d", i); for(j = 1; j <= total_vertex; j++) { printf("%-4d", weight_matrix[i][j]); } printf("\n"); } printf("\n"); } /*圖形之蹤向優先搜尋*/ void dfs(int v) { Node *ptr; int w; printf("V%d ",adjlist[v]->vertex); visited[v] = TRUE; /*設定v頂點為已拜訪過*/ ptr = adjlist[v]->link; /*拜訪相鄰頂點*/ do { /* 若頂點尚未走訪,則以此頂點為新啟始點繼續 做蹤向優先搜尋法走訪,否則找與其相鄰的頂點 直到所有相連接的節點都已走訪 */ w = ptr->vertex; if (!visited[w]) dfs(w); else ptr = ptr->link; } while (ptr != NULL); } /*搜尋串列最後節點函數*/ Node *searchlast( Node *linklist ) { Node *ptr; ptr = linklist; while (ptr->link != NULL) ptr = ptr->link; return ptr; }