/** * File: graph_bfs.c * Created Time: 2023-07-11 * Author: NI-SW (947743645@qq.com) */ #include "graph_adjacency_list.c" /* 哈希表 */ struct hashTable { unsigned int size; unsigned int *array; }; typedef struct hashTable hashTable; /* 初始化哈希表 */ hashTable *newHash(unsigned int size) { hashTable *h = (hashTable *)malloc(sizeof(hashTable)); h->array = (unsigned int *)malloc(sizeof(unsigned int) * size); memset(h->array, 0, sizeof(unsigned int) * size); h->size = size; return h; } /* 标记索引过的顶点 */ void hashMark(hashTable *h, int index) { h->array[index % h->size] = 1; } /* 查询顶点是否已被标记 */ int hashQuery(hashTable *h, int index) { // 若顶点已被标记,则返回 0 if (h->array[index % h->size] == 1) { return 0; } else { return 1; } } /* 释放哈希表内存 */ void freeHash(hashTable *h) { free(h->array); free(h); } /* 队列 */ struct queue { Vertex **list; unsigned int size; int head; int tail; }; typedef struct queue queue; /* 初始化队列 */ queue *newQueue(unsigned int size) { queue *q = (queue *)malloc(sizeof(queue)); q->size = size; q->list = (Vertex **)malloc(sizeof(Vertex *) * size); q->head = 0; q->tail = 0; return q; } /* 入队 */ void queuePush(queue *q, Vertex *v) { q->list[q->tail] = v; q->tail++; } /* 出队 */ void queuePop(queue *q) { q->head++; } /* 队首元素 */ Vertex *queueTop(queue *q) { return q->list[q->head]; } /* 释放队列内存 */ void freeQueue(queue *q) { free(q->list); free(q); } /* 广度优先遍历 */ void graphBFS(graphAdjList *t) { // 初始化队列与哈希表 queue *que = newQueue(t->size); hashTable *visited = newHash(t->size); // 将第一个元素入队 queuePush(que, t->verticesList[0]); hashMark(visited, t->verticesList[0]->pos); printf("\n["); while (que->head < que->tail) { // 遍历该顶点的边链表,将所有与该顶点有连接的,并且未被标记的顶点入队 Node *n = queueTop(que)->linked->head->next; while (n != 0) { // 查询哈希表,若该索引的顶点已入队,则跳过,否则入队并标记 if (hashQuery(visited, n->val->pos) != 0) { queuePush(que, n->val); hashMark(visited, n->val->pos); } n = n->next; } // 打印队首元素 if (que->head == que->tail - 1) { printf("%d]\n", queueTop(que)->val); } else { printf("%d, ", queueTop(que)->val); } // 队首元素出队 queuePop(que); } printf("\n"); // 释放队列与哈希表内存 freeQueue(que); freeHash(visited); } int main() { /* 初始化无向图 */ graphAdjList *graph = newGraphic(3); // 初始化顶点 for (int i = 0; i < 10; i++) { addVertex(graph, i); } // 初始化边 addEdge(graph, 0, 1); addEdge(graph, 0, 3); addEdge(graph, 1, 2); addEdge(graph, 1, 4); addEdge(graph, 2, 5); addEdge(graph, 3, 4); addEdge(graph, 3, 6); addEdge(graph, 4, 5); addEdge(graph, 4, 7); addEdge(graph, 5, 8); addEdge(graph, 6, 7); addEdge(graph, 7, 8); printf("\n初始化后,图为:\n"); printGraph(graph); printf("\n广度优先遍历(BFS)顶点序列为"); graphBFS(graph); return 0; }