/* 圖形的追蹤: 相鄰串列與廣度優先搜尋法(BFS)*/ #include #include #define MAX_V 100 /*最大節點數*/ #define TRUE 1 #define FALSE 0 /*定義資料結構*/ typedef struct node_tag { int vertex; struct node_tag *link; } Node; /*定義佇列結構*/ typedef struct { int items[MAX_V]; int front; int rear; } Queue; Node *adjlist[MAX_V+1]; /*宣告相鄰串列*/ int visited[MAX_V+1]; /*記錄頂點是否已拜訪*/ int total_vertex; void build_adjlist(void); void show_adjlist(void); void bfs(int); Node *searchlast(Node *); /*佇列操作函數*/ Queue* createQueue() { Queue *q = (Queue*)malloc(sizeof(Queue)); q->front = -1; q->rear = -1; return q; } int isEmpty(Queue* q) { return q->front == -1; } void enqueue(Queue* q, int value) { if(q->front == -1) q->front = 0; q->rear++; q->items[q->rear] = value; } int dequeue(Queue* q) { int item = q->items[q->front]; if(q->front == q->rear) { q->front = -1; q->rear = -1; } else { q->front++; } return item; } int main() { build_adjlist(); /*以相鄰串列表示圖形*/ show_adjlist(); /*顯示串列之資料*/ puts("\n------Breadth First Search------"); bfs(1); /*圖形之廣度優先搜尋,以頂點1為啟始頂點*/ printf("\n"); return 0; } void build_adjlist() { FILE *fptr; Node *node,*lastnode; int vi,vj ,weight; fptr = fopen("dfs_1.dat", "r"); if (fptr == NULL) { perror("dfs.dat"); exit(0); } /* 讀取節點總數 */ fscanf(fptr, "%d", &total_vertex); 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 = 1; vj <= total_vertex; vj++) { fscanf(fptr,"%d",&weight); /* 資料檔以相鄰矩陣格式儲存,以1代表相鄰 0 代表不相鄰,將相鄰頂點鏈結在各串列後 */ if (weight != 0) { node = (Node *)malloc(sizeof(Node)); node->vertex = vj; node->link = NULL; lastnode = searchlast(adjlist[vi]); 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 bfs(int start) { Queue* q = createQueue(); Node* ptr; // 將起始節點加入佇列 enqueue(q, start); visited[start] = TRUE; while(!isEmpty(q)) { // 從佇列取出節點並印出 int currentVertex = dequeue(q); printf("V%d ", currentVertex); // 將所有相鄰且未拜訪的節點加入佇列 ptr = adjlist[currentVertex]->link; while(ptr != NULL) { if(!visited[ptr->vertex]) { enqueue(q, ptr->vertex); visited[ptr->vertex] = TRUE; } ptr = ptr->link; } } free(q); } /*搜尋串列最後節點函數*/ Node *searchlast(Node *linklist) { Node *ptr; ptr = linklist; while (ptr->link != NULL) ptr = ptr->link; return ptr; }