// 更新距离数组和 visited 数组 while (minIt != graph.points.end()) { int curr = minIt->first; visited[curr] = true; for (unordered_map<int, int>::iterator it = graph.edges[curr].begin(); it != graph.edges[curr].end(); it++) { int neighbor = it->first; int weight = it->second; if (!visited[neighbor] && dist[curr] + weight < dist[neighbor]) { dist[neighbor] = dist[curr] + weight; } } // 找到距离起点最近的未访问点 minIt = graph.points.end(); for (unordered_map<int, Point>::iterator it = graph.points.begin(); it != graph.points.end(); it++) { if (!visited[it->first] && (minIt == graph.points.end() || dist[it->first] < dist[minIt->first])) { minIt = it; } } }
时间: 2024-02-15 20:27:47 浏览: 64
这段代码是 Dijkstra 算法的实现,用于寻找图中两点之间的最短路径。其中,dist 数组用于存储起点到各点的最短距离,visited 数组用于记录各点是否被访问过。该算法的基本思想是从起点开始,每次选择距离起点最近的未访问点作为下一个当前点,然后更新与该点相邻的点的最短距离。不断重复这个过程,直到所有点都被访问过为止。
具体实现中,首先将起点的距离设为 0,其余点的距离设为无穷大(这里用 INT_MAX 表示)。然后选择距离起点最近的未访问点作为当前点,更新其相邻点的距离。接着再从所有未访问的点中选择距离起点最近的点作为下一个当前点,重复上述过程,直到所有点都被访问过为止。
具体实现中,第一次循环时,先找到距离起点最近的未访问点,将其设为当前点,并将其距离设为 dist[curr]。然后遍历当前点的相邻点,如果该相邻点未被访问过且通过当前点到该相邻点的距离比原来的距离更短,则更新其距离。接着再次找到距离起点最近的未访问点作为当前点,重复上述过程,直到所有点都被访问过为止。
相关问题
void DFSTraverse(Graph graph) { for (int i = 1; i <= graph->vexnum; i++) visited[i] = false; for (int i = 1; i <= graph->vexnum; i++) { if (!visited[i]) DFS(graph, i); } } void DFS(Graph graph, int v) { visited[v] = true; cout << graph->list[v].data << " "; Node* header = graph->list[v].head; while (header) { if (!visited[header->vex]) { DFS(graph, header->vex); } header = header->next; } } void BFSTraverse(Graph graph) { queue<int> MyQueue; for (int i = 1; i <= graph->vexnum; i++) visited[i] = false; for (int i = 1; i <= graph->vexnum; i++) { if (!visited[i]) { visited[i] = true; cout << graph->list[i].data << " "; MyQueue.push(i); while (!MyQueue.empty()) { int front = MyQueue.front(); MyQueue.pop(); Node* header = graph->list[front].head; while (header) { if (!visited[header->vex]) { visited[header->vex] = true; cout << graph->list[header->vex].data << " "; MyQueue.push(header->vex); } header = header->next; } } } } } void printGraph(Graph graph) { int** arr = new int* [graph->vexnum + 1]; for (int i = 1; i <= graph->vexnum; i++) { arr[i] = new int[graph->vexnum + 1]; } for (int i = 1; i <= graph->vexnum; i++) { for (int j = 1; j <= graph->vexnum; j++) { arr[i][j] = 0; } } for (int i = 1; i <= graph->vexnum; i++) { Node* header = graph->list[i].head; while (header) { arr[i][header->vex] = header->weight; header = header->next; } } for (int i = 1; i <= graph->vexnum; i++) { for (int j = 1; j <= graph->vexnum; j++) { cout << arr[i][j] << " "; } cout << endl; } }代码讲解
DFSTraverse函数和DFS函数实现了图的深度优先遍历。首先将visited数组初始化为false,然后对每个顶点进行深度优先遍历。在DFS函数中,首先将当前顶点标记为已访问,并输出其数据。然后遍历当前顶点的邻接表,对于每个未被访问过的邻接点,递归调用DFS函数进行遍历。
BFSTraverse函数实现了图的广度优先遍历。同样先将visited数组初始化为false,然后对每个未被访问过的顶点进行广度优先遍历。在遍历每个顶点时,将其标记为已访问,输出其数据,并将其加入队列中。然后对队列中的元素依次出队,并遍历其邻接表,对于每个未被访问过的邻接点,将其标记为已访问,输出其数据,并将其加入队列中。
printGraph函数用于输出图的邻接矩阵。首先动态创建一个二维数组arr来存储邻接矩阵。然后将其初始化为0。接着遍历每个顶点的邻接表,将对应的邻接矩阵元素赋值为边的权重。最后输出邻接矩阵。
#include "graph.h" #include <stdio.h> #include <stdlib.h> void CreateAdj(AdjGraph &G,int A[MAXV][MAXV],int n,int e) //创建图的邻接表 { int i,j; ArcNode p; G=(AdjGraph )malloc(sizeof(AdjGraph)); for(i=0;i<n;i++) //给邻接表的头元素的指针域置初值 { G->adjlist[i].firstarc=NULL; } for(i=0;i<n;i++) //检查邻接表的每个元素 { for(j=n-1;j>=0;j--) { if(A[i][j]!=0&&A[i][j]!=INF) //存在一条边 { p=(ArcNode )malloc(sizeof(ArcNode)); //创建一个结点p p->adjvex=j; //存放邻接点 p->weight=A[i][j]; //存放权 p->nextarc=G->adjlist[i].firstarc; //采用头插法插入结点p G->adjlist[i].firstarc=p; } } } G->n=n; G->e=e; } void DispAdj(AdjGraph G) { int i; ArcNode p; for(i=0;i<G->n;i++) { p=G->adjlist[i].firstarc; printf("%3d: ",i); while(p!=NULL) { printf("%d[%d]→",p->adjvex,p->weight); p=p->nextarc; } printf("^\n"); } } void DestroyAdj(AdjGraph &G) { int i; ArcNode pre,p; for(i=0;i<G->n;i++) //扫描所有单链表 { pre=G->adjlist[i].firstarc; //p指向第i个单链表的头结点 if(pre!=NULL) { p=pre->nextarc; while(p!=NULL) //释放第i个单链表的所有结点 { free(pre); pre=p; p=p->nextarc; } free(pre); } } free(G); } //深度优先遍历 int visited[MAXV]; //全局数组,记录访问的点 void DFS(AdjGraph G,int v) { / Begin / / End **********/ }:请实现Begin与End之间的代码
根据题目要求,需要在`DFS`函数中实现深度优先遍历。下面给出一个较为详细的实现过程:
```c
void DFS(AdjGraph G, int v)
{
ArcNode p;
visited[v] = 1; // 标记顶点v已经被访问过
printf("%d ", v); // 输出访问顶点v的信息
p = G.adjlist[v].firstarc;
while(p != NULL) // 遍历顶点v的邻接点
{
if(!visited[p->adjvex]) // 如果邻接点未被访问,则递归访问该邻接点
{
DFS(G, p->adjvex);
}
p = p->nextarc; // 继续遍历下一个邻接点
}
}
```
在`DFS`函数中,首先标记当前顶点v已经被访问过,然后输出访问顶点v的信息。接着遍历顶点v的邻接点,如果邻接点未被访问,则递归访问该邻接点。最后继续遍历下一个邻接点。需要注意的是,在`DFS`函数外部需要定义一个全局数组`visited`,用于记录已经访问过的顶点。
阅读全文