C语言创建无向图,广度优先算法进行图的遍历求从0到4的最短路径和长度,输出遍历结果
时间: 2024-02-15 17:02:45 浏览: 72
无向图建立、深度优先遍历和广度优先遍历实现算法[借鉴].pdf
5星 · 资源好评率100%
好的,我可以帮你解答这个问题。首先,我们需要定义一个结构体来表示图的节点:
```c
typedef struct GraphNode {
int val; // 节点的值
int visited; // 是否被访问过
struct GraphNode** neighbors; // 节点的邻居指针数组
int numNeighbors; // 节点的邻居个数
} GraphNode;
```
然后,我们可以按照以下方式创建一个无向图:
```c
GraphNode* createGraphNode(int val, int numNeighbors) {
GraphNode* node = (GraphNode*) malloc(sizeof(GraphNode));
node->val = val;
node->visited = 0;
node->neighbors = (GraphNode**) malloc(numNeighbors * sizeof(GraphNode*));
node->numNeighbors = numNeighbors;
return node;
}
void addUndirectedEdge(GraphNode* node1, GraphNode* node2) {
node1->neighbors[node1->numNeighbors++] = node2;
node2->neighbors[node2->numNeighbors++] = node1;
}
GraphNode* createGraph() {
GraphNode* node0 = createGraphNode(0, 2);
GraphNode* node1 = createGraphNode(1, 2);
GraphNode* node2 = createGraphNode(2, 3);
GraphNode* node3 = createGraphNode(3, 2);
GraphNode* node4 = createGraphNode(4, 1);
addUndirectedEdge(node0, node1);
addUndirectedEdge(node0, node2);
addUndirectedEdge(node1, node2);
addUndirectedEdge(node2, node3);
addUndirectedEdge(node3, node4);
return node0;
}
```
这个无向图包含了5个节点,分别是0、1、2、3、4,它们之间的关系如下:
```
0 -- 1
| |
2 -- 3 -- 4
```
接下来,我们可以编写广度优先搜索算法来遍历这个无向图,并求出从节点0到节点4的最短路径和长度。具体实现如下:
```c
typedef struct QueueNode {
GraphNode* node; // 节点指针
int distance; // 距离起点的距离
struct QueueNode* next;
} QueueNode;
typedef struct Queue {
QueueNode* front;
QueueNode* rear;
} Queue;
Queue* createQueue() {
Queue* q = (Queue*) malloc(sizeof(Queue));
q->front = NULL;
q->rear = NULL;
return q;
}
void enqueue(Queue* q, GraphNode* node, int distance) {
QueueNode* qNode = (QueueNode*) malloc(sizeof(QueueNode));
qNode->node = node;
qNode->distance = distance;
qNode->next = NULL;
if (q->front == NULL) {
q->front = qNode;
q->rear = qNode;
} else {
q->rear->next = qNode;
q->rear = qNode;
}
}
QueueNode* dequeue(Queue* q) {
if (q->front == NULL) {
return NULL;
}
QueueNode* qNode = q->front;
q->front = q->front->next;
if (q->front == NULL) {
q->rear = NULL;
}
return qNode;
}
void bfs(GraphNode* start, GraphNode* end) {
Queue* q = createQueue();
enqueue(q, start, 0);
start->visited = 1;
while (q->front != NULL) {
QueueNode* qNode = dequeue(q);
GraphNode* node = qNode->node;
int distance = qNode->distance;
free(qNode);
if (node == end) {
printf("最短路径长度为:%d\n", distance);
break;
}
printf("访问节点:%d\n", node->val);
for (int i = 0; i < node->numNeighbors; i++) {
GraphNode* neighbor = node->neighbors[i];
if (!neighbor->visited) {
neighbor->visited = 1;
enqueue(q, neighbor, distance + 1);
}
}
}
}
int main() {
GraphNode* graph = createGraph();
bfs(graph, graph + 4);
return 0;
}
```
在这个程序中,我们使用了一个队列来实现广度优先搜索。首先将起点0入队,并将其标记为已访问。然后循环从队列中取出节点,遍历它的所有邻居节点,如果邻居节点没有被访问过,则将其入队,并将其标记为已访问。当取出的节点为终点4时,输出最短路径的长度,并结束搜索。
你可以在本地编译运行这个程序,查看输出结果。
阅读全文