解释代码( for(int k=0;k<G.arcnum;k++) { int i,j; char v1,v2; int c; printf("请输入(Vi,Vj)对应的顶点及长度:\n"); cin>>v1>>v2>>c; //输入一条边依附的两个顶点及权值 Edge[k].Head=v1; Edge[k].Tail=v2; Edge[k].lowcost=c; i = LocateVex(G,v1); j = LocateVex(G,v2); G.arcs[i][j]=G.arcs[j][i]=c; } } typedef struct Closedge { VerTexType adjvex;//最小边在U中的那个顶点 ArcType lowcost;//最小边上的权值 }closedge[MVNum]; int Min(closedge SZ,AMGraph G)//求出第k个顶点,closedge[k]中存有当前最小边 { int i=0,j,k,min; while(!SZ[i].lowcost) i++; min=SZ[i].lowcost; k=i; for(j=i+1;j<G.vexnum;j++) { if(SZ[j].lowcost>0) { if(min>SZ[j].lowcost) { min=SZ[j].lowcost; k=j; } } } return k; } void prim(AMGraph G,VerTexType u)//p算法 {//无向图G以邻接矩阵形式存储,从顶点u出发构造G的最小生成树T,输出T的各条边 closedge closedge; int k=LocateVex(G,u);//k为顶点u的下标 for(int j=0;j<G.vexnum;j++)//对V-U的每一个顶点vj,初始化closedge[j] { closedge[j].adjvex=u; closedge[j].lowcost=G.arcs[k][j]; } closedge[k].lowcost=0;//初始,U={u} )
时间: 2024-04-21 22:26:06 浏览: 84
这段代码实现了Prim算法,用于求解无向图的最小生成树。首先,通过for循环和LocateVex函数输入每条边的信息,包括边的起点、终点和权值,并将这些信息存储在Edge数组中。接下来,定义了一个结构体Closedge用于存储最小生成树的各个节点的信息,包括最小边在U中的那个顶点和最小边上的权值。Min函数用于求出第k个顶点,closedge[k]中存有当前最小边。最后,prim函数用于构造最小生成树,首先对V-U的每个顶点vj进行初始化,将closedge[j].adjvex设置为起点u,将closedge[j].lowcost设置为起点u到vj的距离。然后将起点u加入U中,将closedge[k].lowcost设置为0,表示已经访问过。
相关问题
#include <stdio.h> #define INFINITY 32768 typedef enum{DG,DN,UDG,UDN}GraphKind; #define MaxVexNum 20 //最大顶点数目 typedef char ElemType; typedef struct { ElemType vexs[MaxVexNum]; int arcs[MaxVexNum][MaxVexNum]; int vexnum, arcnum; }AMGraph; typedef struct ArcNode{ int adj; }ArcNode; int locate(AMGraph G,char v) { int k; for(k=0;k<G.vexnum;k++) { if(G.vexs[k]==v) { return k; } } return -1; } void CreatMGraph(AMGraph G) { int i,j,k; char v1,v2; scanf("%d%d",&G.vexnum,&G.arcnum); getchar(); for(i=0;i<G.vexnum;i++) { for(j=0;j<G.vexnum;j++) { G.arcs[i][j]=0; } } for(i=0;i<G.vexnum;i++) { scanf("%c",&G.vexs[i]); } getchar(); for(k=0;k<G.arcnum;k++) { scanf("%c%c",&v1,&v2); getchar(); i=locate(G,v1); j=locate(G,v2); G.arcs[i][j]=1; G.arcs[j][i]=1; } } int visited[MaxVexNum]; void DepthFirstSearch(AMGraph g,int v0) { printf("%c",g.vexs[v0]);visited[v0]=1; for(int vj=0;vj<g.vexnum;vj++) { if(!visited[vj]&&g.arcs[v0][vj]==1) { DepthFirstSearch(g,vj); } } } void TraverseGraph(AMGraph g) { for(int vi=0;vi<g.vexnum;vi++) { visited[vi]=0; } for(int vi=0;vi<g.vexnum;vi++) { if(!visited[vi]) DepthFirstSearch(g,vi); } } int main() { AMGraph G; CreatMGraph(G); TraverseGraph(G); return 0; }哪错了
在该程序中存在以下问题:
1. 在函数 `CreatMGraph` 中,应该传入指针类型的参数 `AMGraph *G`,否则函数中对 `G` 的修改不会影响到主函数中的 `G` 变量。
2. 在 `CreatMGraph` 中,应该使用 `scanf("%d%d",&G->vexnum,&G->arcnum);` 以及 `scanf(" %c",&G->vexs[i]);` 和 `scanf("%c%c",&v1,&v2); getchar();`,其中 `%d` 和 `%c` 之间应该加上空格,否则会有输入格式上的问题。
3. 在 `DepthFirstSearch` 函数中,应该在递归调用前先进行标记,否则会死循环或者输出结果不正确。
修改后的代码如下所示:
```c
#include <stdio.h>
#include <stdlib.h>
#define INFINITY 32768
#define MaxVexNum 20
typedef char ElemType;
typedef enum {DG, DN, UDG, UDN} GraphKind;
typedef struct {
ElemType vexs[MaxVexNum];
int arcs[MaxVexNum][MaxVexNum];
int vexnum, arcnum;
} AMGraph;
void CreatMGraph(AMGraph *G) {
int i, j, k;
char v1, v2;
scanf("%d%d", &G->vexnum, &G->arcnum);
getchar();
for (i = 0; i < G->vexnum; i++) {
for (j = 0; j < G->vexnum; j++) {
G->arcs[i][j] = 0;
}
}
for (i = 0; i < G->vexnum; i++) {
scanf(" %c", &G->vexs[i]);
}
getchar();
for (k = 0; k < G->arcnum; k++) {
scanf("%c%c", &v1, &v2);
getchar();
i = locate(*G, v1);
j = locate(*G, v2);
G->arcs[i][j] = 1;
G->arcs[j][i] = 1;
}
}
int locate(AMGraph G, char v) {
int k;
for (k = 0; k < G.vexnum; k++) {
if (G.vexs[k] == v) {
return k;
}
}
return -1;
}
int visited[MaxVexNum];
void DepthFirstSearch(AMGraph g, int v0) {
visited[v0] = 1;
printf("%c", g.vexs[v0]);
for (int vj = 0; vj < g.vexnum; vj++) {
if (!visited[vj] && g.arcs[v0][vj] == 1) {
DepthFirstSearch(g, vj);
}
}
}
void TraverseGraph(AMGraph g) {
for (int vi = 0; vi < g.vexnum; vi++) {
visited[vi] = 0;
}
for (int vi = 0; vi < g.vexnum; vi++) {
if (!visited[vi]) {
DepthFirstSearch(g, vi);
}
}
}
int main() {
AMGraph G;
CreatMGraph(&G);
TraverseGraph(G);
return 0;
}
```
#include<iostream> #include<queue> using namespace std; #define MAXNUM 100 char visited1[MAXNUM]; typedef struct{ char vexs[MAXNUM]; //顶点 int arcs[MAXNUM][MAXNUM];//边 int vexnum,arcnum; } AMGraph; int LocateVex(AMGraph G,char v){ for(int i = 0; i < G.vexnum; i++){ if(G.vexs[i] == v)return i; } return -1; } int CreateUNG(AMGraph &G){ char v1,v2; cout<<"请输入顶点数和边数:"; cin>>G.vexnum>>G.arcnum; cout<<"请依次输入顶点:"; for(int i = 0; i < G.vexnum; i++)cin>>G.vexs[i]; for(int j = 0; j < G.vexnum; j++) for(int i = 0; i < G.vexnum; i++) G.arcs[j][i] = 0; //初始化邻接矩阵 cout<<"请依次输入邻边:"<<endl; for(int k = 0; k < G.arcnum; k++){ cin>>v1>>v2; int i = LocateVex(G,v1); int j = LocateVex(G,v2); G.arcs[i][j] = 1; G.arcs[j][i] = 1; } return 1; } void DFT_AM(AMGraph G,int i){ //深度优先遍历邻接矩阵 cout<<G.vexs[i]; visited1[i] = 1; for(int j = 0; j < G.vexnum; j++){ if(G.arcs[i][j] == 1 && !visited1[j])DFT_AM(G,j); } } void BFT_AM(AMGraph G, int i) { //广度优先遍历邻接矩阵 queue<int> Q; //定义队列Q Q.push(i); //将起始顶点入队 visited1[i] = 1; //标记为已访问 while (!Q.empty()) { //重复步骤2-3,直到队列为空 int cur = Q.front(); //取出队首元素 Q.pop(); //出队 cout << G.vexs[cur]; //访问该顶点 for (int j = 0; j < G.vexnum; j++) { if (G.arcs[cur][j] == 1 && !visited1[j]) { //遍历该顶点的邻接点,将未访问的邻接点入队 Q.push(j); visited1[j] = 1; //标记为已访问 } } } } int main(){ AMGraph G; CreateUNG(G); for(int j = 0; j < G.vexnum; j++){ //输出邻接矩阵 for(int i = 0; i < G.vexnum; i++) cout<<G.arcs[j][i]<<" "; cout<<endl; } cout<<endl<<"输出深度优先序列:"; DFT_AM(G,0); cout << endl << "输出广度优先序列:"; for (int i = 0; i < MAXNUM; i++) visited1[i] = 0; //重置visited1数组 BFT_AM(G, 0); } 请改良此代码
以下是对代码的改良建议:
1. 在定义结构体时,使用结构体名称作为前缀,提高可读性。
2. 使用枚举类型来定义遍历方法,提高可读性。
3. 将遍历方法的参数从顶点序号改为顶点名称,提高可读性。
4. 在遍历时,将访问过的顶点入栈或入队,不必使用全局变量visited1。
5. 将创建图的函数返回值改为bool类型,表示创建是否成功。
6. 在输入邻边时,应该检查输入的两个顶点是否合法,避免数组越界。
下面是改良后的代码:
```c++
#include<iostream>
#include<stack>
#include<queue>
using namespace std;
#define MAXNUM 100
typedef struct AMGraph{
char vexs[MAXNUM]; //顶点
int arcs[MAXNUM][MAXNUM];//边
int vexnum,arcnum;
} AMGraph;
enum TraverseMethod{
DEPTH_FIRST_TRAVERSE,
BREADTH_FIRST_TRAVERSE
};
int LocateVex(AMGraph G, char v){
for(int i = 0; i < G.vexnum; i++){
if(G.vexs[i] == v) return i;
}
return -1;
}
bool CreateUNG(AMGraph &G){
char v1,v2;
cout<<"请输入顶点数和边数:";
cin>>G.vexnum>>G.arcnum;
if(G.vexnum <= 0 || G.arcnum <= 0) return false;
cout<<"请依次输入顶点:";
for(int i = 0; i < G.vexnum; i++) cin>>G.vexs[i];
for(int j = 0; j < G.vexnum; j++){
for(int i = 0; i < G.vexnum; i++) G.arcs[j][i] = 0; //初始化邻接矩阵
}
cout<<"请依次输入邻边:"<<endl;
for(int k = 0; k < G.arcnum; k++){
cin>>v1>>v2;
int i = LocateVex(G,v1);
int j = LocateVex(G,v2);
if(i == -1 || j == -1){
cout << "输入的边不合法,请重新输入!" << endl;
k--;
continue;
}
G.arcs[i][j] = 1;
G.arcs[j][i] = 1;
}
return true;
}
void Traverse_AM(AMGraph G, char v, TraverseMethod method){
bool visited[MAXNUM] = {false};
stack<int> S;
queue<int> Q;
int i = LocateVex(G, v);
if(i == -1) return;
if(method == DEPTH_FIRST_TRAVERSE){ //深度优先遍历邻接矩阵
S.push(i);
visited[i] = true;
while(!S.empty()){
int cur = S.top();
S.pop();
cout << G.vexs[cur];
for(int j = G.vexnum - 1; j >= 0; j--){
if(G.arcs[cur][j] == 1 && !visited[j]){
S.push(j);
visited[j] = true;
}
}
}
}
else if(method == BREADTH_FIRST_TRAVERSE){ //广度优先遍历邻接矩阵
Q.push(i);
visited[i] = true;
while(!Q.empty()){
int cur = Q.front();
Q.pop();
cout << G.vexs[cur];
for(int j = 0; j < G.vexnum; j++){
if(G.arcs[cur][j] == 1 && !visited[j]){
Q.push(j);
visited[j] = true;
}
}
}
}
}
int main(){
AMGraph G;
if(CreateUNG(G)){
for(int j = 0; j < G.vexnum; j++){ //输出邻接矩阵
for(int i = 0; i < G.vexnum; i++) cout<<G.arcs[j][i]<<" ";
cout<<endl;
}
cout<<endl<<"输出深度优先序列:";
Traverse_AM(G, G.vexs[0], DEPTH_FIRST_TRAVERSE);
cout << endl << "输出广度优先序列:";
Traverse_AM(G, G.vexs[0], BREADTH_FIRST_TRAVERSE);
}
return 0;
}
```
阅读全文