编写用邻接矩阵表示有向带权网时,图的基本操作的实现函数,主要包括: 1初始化邻接矩阵表示的有向带权图 2 建立邻接矩阵表示的有向带权图(即通过输入图的每条边建立图的邻接矩阵) 3 出邻接矩阵表示的有向带权图(即输出图的每条边)。 4编写求最短路径的DijKstra算法函数 void Dijkstra(adjmatrix GA,int dist[],edgenode *path[], int i, int n),该算法求从顶点i到其余顶点的最短 路径与最短路径长度,并分别存于数组path和dist中。(可选) 5 编写打印输出从源点到每个顶点的最短路径及长度的函数 void PrintPath(int dist[], edgenode *path[],int n)。(可选) 同时建立一个验证操作实现的主函数main)进行测试。数据结构,使用c++语言
时间: 2024-02-16 12:00:09 浏览: 85
好的,我来一一回答您的问题。首先,我们需要定义一个结构体来表示有向带权图的边:
```c++
struct EdgeNode {
int weight; // 边的权重
int end; // 边的终点
EdgeNode *next; // 指向下一条边的指针
};
```
接下来,我们定义一个邻接矩阵表示有向带权图的结构体:
```c++
struct AdjMatrix {
int **matrix; // 存储邻接矩阵的二维数组
int n; // 图中顶点数
};
```
其中,`matrix`是一个二维数组,`n`表示图中顶点数。接下来,我们逐个实现图的基本操作:
1. 初始化邻接矩阵表示的有向带权图
```c++
void InitGraph(AdjMatrix& G, int n) {
G.n = n;
G.matrix = new int*[n];
for (int i = 0; i < n; i++) {
G.matrix[i] = new int[n];
for (int j = 0; j < n; j++) {
G.matrix[i][j] = INT_MAX; // 初始化为无穷大
}
}
}
```
这个函数接受一个`AdjMatrix`类型的参数`G`,以及一个正整数`n`,表示图中顶点数。函数首先将`G.n`赋值为`n`,然后为`G.matrix`分配内存,并将所有元素初始化为无穷大。
2. 建立邻接矩阵表示的有向带权图
```c++
void BuildGraph(AdjMatrix& G) {
int m; // 边的条数
int start, end, weight;
cin >> m;
for (int i = 0; i < m; i++) {
cin >> start >> end >> weight;
G.matrix[start][end] = weight;
}
}
```
这个函数接受一个`AdjMatrix`类型的参数`G`,从标准输入中读入边的条数`m`,以及每条边的起点、终点和权重,并将这些信息存储到邻接矩阵`G.matrix`中。
3. 输出邻接矩阵表示的有向带权图
```c++
void PrintGraph(AdjMatrix G) {
int n = G.n;
for (int i = 0; i < n; i++) {
for (int j = 0; j < n; j++) {
if (G.matrix[i][j] == INT_MAX) {
cout << "INF" << " ";
} else {
cout << G.matrix[i][j] << " ";
}
}
cout << endl;
}
}
```
这个函数接受一个`AdjMatrix`类型的参数`G`,输出邻接矩阵`G.matrix`中的所有元素。如果某个元素的值为无穷大,则输出"INF"。
4. Dijkstra算法
```c++
void Dijkstra(AdjMatrix G, int dist[], EdgeNode *path[], int start, int n) {
// 初始化
bool *visited = new bool[n];
for (int i = 0; i < n; i++) {
visited[i] = false;
dist[i] = G.matrix[start][i];
if (dist[i] == INT_MAX) {
path[i] = NULL;
} else {
path[i] = new EdgeNode{dist[i], i, NULL};
}
}
visited[start] = true;
// 开始计算
for (int k = 1; k < n; k++) {
int minDist = INT_MAX;
int u = -1;
for (int i = 0; i < n; i++) {
if (!visited[i] && dist[i] < minDist) {
minDist = dist[i];
u = i;
}
}
if (u == -1) {
break;
}
visited[u] = true;
for (int i = 0; i < n; i++) {
if (!visited[i] && G.matrix[u][i] < INT_MAX) {
int newDist = dist[u] + G.matrix[u][i];
if (newDist < dist[i]) {
dist[i] = newDist;
EdgeNode *newPath = new EdgeNode{G.matrix[u][i], i, NULL};
if (path[i] != NULL) {
delete path[i];
}
path[i] = newPath;
EdgeNode *temp = path[u];
while (temp->next != NULL) {
temp = temp->next;
}
temp->next = newPath;
}
}
}
}
delete[] visited;
}
```
这个函数接受一个`AdjMatrix`类型的参数`G`,一个整型数组`dist`,一个指向`EdgeNode`类型的指针数组`path`,一个整数`start`表示起点,以及一个整数`n`表示图中顶点数。函数会计算从起点`start`到其余顶点的最短路径和路径长度,并将结果分别存储到`dist`和`path`数组中。
5. 输出从源点到每个顶点的最短路径及长度
```c++
void PrintPath(int dist[], EdgeNode *path[], int n) {
for (int i = 0; i < n; i++) {
cout << "Path to " << i << " with distance " << dist[i] << ": ";
if (dist[i] == INT_MAX) {
cout << "No path" << endl;
} else {
EdgeNode *temp = path[i];
cout << i;
while (temp != NULL) {
cout << " <- " << temp->end;
temp = temp->next;
}
cout << endl;
}
}
}
```
这个函数接受一个整型数组`dist`,一个指向`EdgeNode`类型的指针数组`path`,以及一个整数`n`表示图中顶点数。函数会输出从源点到每个顶点的最短路径及长度。
最后,我们编写一个验证操作实现的主函数`main`:
```c++
int main() {
AdjMatrix G;
int n;
cin >> n;
InitGraph(G, n);
BuildGraph(G);
PrintGraph(G);
int *dist = new int[n];
EdgeNode **path = new EdgeNode*[n];
for (int i = 0; i < n; i++) {
path[i] = NULL;
}
Dijkstra(G, dist, path, 0, n);
PrintPath(dist, path, n);
return 0;
}
```
这个函数首先从标准输入中读入图中顶点数`n`,然后初始化邻接矩阵、建立邻接矩阵、输出邻接矩阵、计算最短路径并输出结果。
阅读全文