#include
#include
#define MAXVEX 100
#define INFINITY 65535
typedef int EdgeType;
typedef char VertexType;
typedef struct {
VertexType vexs[MAXVEX];
EdgeType arc[MAXVEX][MAXVEX];
int numVertexes, numEdges;
} MGraph;
void CreateMGraph(MGraph *g) {
int i, j, k, w;
printf("輸入頂點數和邊數:\\n");
if (scanf("%d %d", &g->numVertexes, &g->numEdges) != 2) return;
getchar(); // 吸收換行符
printf("輸入 %d 個頂點字符:\\n", g->numVertexes);
for (i = 0; i < g->numVertexes; i++) {
scanf("%c", &g->vexs[i]);
getchar(); // 每次吸收換行
}
// 初始化鄰接矩陣
for (i = 0; i < g->numVertexes; i++)
for (j = 0; j < g->numVertexes; j++)
g->arc[i][j] = INFINITY;
printf("輸入邊 (vi, vj) 的下標 i, j 和權 w:\\n");
for (k = 0; k < g->numEdges; k++) {
if (scanf("%d %d %d", &i, &j, &w) != 3) break;
if (i >= 0 && i < g->numVertexes && j >= 0 && j < g->numVertexes) {
g->arc[i][j] = w;
g->arc[j][i] = w; // 無向圖
}
}
}
void PrintGraphEdges(const MGraph *g) {
printf("圖的所有邊:\\n");
for (int i = 0; i < g->numVertexes; i++) {
for (int j = i + 1; j < g->numVertexes; j++) { // 只輸出上三角,避免重複
if (g->arc[i][j] != INFINITY && g->arc[i][j] != 0) {
printf("(%c, %c) 權值: %d\\n", g->vexs[i], g->vexs[j], g->arc[i][j]);
}
}
}
}
int main() {
MGraph *g = (MGraph*)malloc(sizeof(MGraph));
if (!g) {
fprintf(stderr, "內存分配失敗\\n");
return 1;
}
CreateMGraph(g);
PrintGraphEdges(g);
free(g);
return 0;
}
| 原問題 | 修復方案 |
|---|---|
| `mgraph* g;` 未分配 | `MGraph *g = malloc(sizeof(MGraph));` 並在 `main` 結束前 `free(g);` |
| 循環條件語法錯誤 | 補全分號、正確變量名 (`i < g->numVertexes`) |
| `scanf("%c")` 讀取換行 | 每次 `scanf("%c")` 後 `getchar()` 吸收換行,或用 `scanf(" %c", ...)` (空格跳過空白) |
| 邊輸出邏輯混亂 | 雙層循環上限用 `numVertexes`,條件判斷 `!= INFINITY`,只輸出上三角避免重複 |
| 缺少錯誤處理 | 檢查 `scanf` 返回值、`malloc` 返回值、下標越界 |
4 4 A B C D 0 1 10 0 2 20 1 2 30 2 3 40
預期輸出:
圖的所有邊: (A, B) 權值: 10 (A, C) 權值: 20 (B, C) 權值: 30 (C, D) 權值: 40
指針必須指向有效內存、循環邊界嚴謹、輸入緩衝區處理得當,是 C 語言數據結構編程的三大鐵律。