Data_Structure/作業/unit12/dfs/dfs_up_triangle.cpp
2025-01-20 21:30:53 +08:00

179 lines
4.2 KiB
C++
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/* file name: dfs.c */
/* 圖形的追蹤: 相鄰串列與蹤向優先搜尋法(DFS)*/
#include <stdio.h>
#include <stdlib.h>
#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("up_1.dat", "r");
if (fptr == NULL) {
perror("up_2.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++) {
/* 讀取該行的數值 */
for (vj = vi ; vj <= total_vertex; 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 的連結(因為是無向圖)
if (vi != vj) { // 避免自環
node = (Node *)malloc(sizeof(Node));
node->vertex = vi;
node->link = NULL;
lastnode = searchlast(adjlist[vj]);
lastnode->link = node;
}
}
}
}
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;
}