아이디어
이 질문은 그래프의 저장 및 순회 (BFS, DFS) 작업을 테스트하는 것입니다.
그래프는 인접 행렬과 인접 목록을 저장하며,이 질문에서는 인접 행렬을 사용하며 인접 행렬을 저장하는 두 가지 방법도 있습니다.
- 2 차원 배열을 정의하여 각 포인트의 모든 간선을 저장합니다. 무 방향 그래프의 경우 각 간선은 두 간선을 저장해야합니다.
- 1 차원 배열을 정의합니다. 무 방향 그래프의 경우 방법 1 (각 모서리에 대해 한 번 저장 됨)에서 2 차원 배열의 하위 삼각 행렬 만 첫 번째 방법에 비해 많은 공간을 절약 할 수 있습니다.
- 두 번째 방법은이 1 차원 배열에서 두 노드 사이의 가장자리 아래 첨자는 다음과 같습니다.
에러 코드
void DFS(int* G, int* visit, int N, int V) {
visit[V] = 1;
printf("%d ", V);
//错误地方
for (int i = V; i < N; i++) {
//遍历每个临界点 对某个点的临界点来说,要按下三角矩阵遍历列
if (G[i * (i + 1) / 2 + V] == 1 && visit[i] != 1) {
DFS(G, visit, N, i);
}
}
}
void BFS(int* G, int* visit, int N, int V) {
visit[V] = 1;
printf("%d ", V);
Enquee(V);
while(!IsEmpty()) {
V = Dequee(); //以下遍历V的临接点
//错误地方
for (int i = V; i < N; i++) {
//遍历每个临接点 对某个点的临接点来说,要按下三角矩阵遍历列
if (G[i * (i + 1) / 2 + V] == 1 && visit[i] != 1) {
visit[i] = 1;
printf("%d ", i);
Enquee(i);
}
}
}
}
해석 오류
매우 이상합니다. 오류 코드가 여전히 전송되는 이유는 무엇입니까?
내 그래프의 저장 방법은 에러 코드에서 공간을 절약하는 두 번째 방법을 사용하기 때문인데 두 번째 방법을 사용하면 어떨까요? ? ?
사례를 살펴 보겠습니다.
10 7
1 4
1 3
1 5
4 2
6 7
6 9
7 8
이 경우 문제는 가장자리 4 2입니다.이 경우의 그림을 그리면 (너무 못 생겼고 그리지 않았습니다) 노드 1과 노드 4 사이에 가장자리가 있고 노드 4와 노드 2에는 가장자리가 있습니다.
- 다시 말해:
트래버스 할 때 먼저 노드 1로 트래버스 한 다음 노드 4로 트래버스하고 마지막으로 노드 2로 트래버스해야합니다.
- 하나두 번째 저장 방법에서는 노드의 인접 행렬을 탐색 할 때 하위 삼각 행렬에 해당하는 열을 탐색하여 1의 값을 찾습니다 (예 : v0 대신 v3에서 시작하여 v3의 인접 지점 탐색). . 따라서 노드 4 의 인접 노드를 탐색 할 때 노드 4에서 시작하여 노드 2를 찾지 못했습니다.
올바른 코드
그래프를 저장하는 데 사용되는 첫 번째 방법은 2 차원 행렬로 저장하여 노드의 인접 행렬을 찾을 때 해당 열이 2 차원이기 때문에 단순히 순회 할 수 있으므로 각 순회는 v0 시작
노트
2 차원 배열을 사용하여 매개 변수를 전달할 때 형식 매개 변수는 배열 포인터를 사용합니다. int (* G) [10]
#include <stdio.h>
#include <stdlib.h>
void DFS(int(* G)[10], int* visit, int N, int V) {
visit[V] = 1;
printf("%d ", V);
for (int i = 0; i < N; i++) {
//遍历每个临界点 对某个点的临界点来说,要按下三角矩阵遍历列
if (G[i][V] == 1 && visit[i] != 1) {
DFS(G, visit, N, i);
}
}
}
struct quee {
int q[10];
int front = 0;
int rear = 0;
}Pq;
void Enquee(int V) {
Pq.q[Pq.rear++] = V;
}
int Dequee() {
return Pq.q[Pq.front++];
}
int IsEmpty() {
if (Pq.front == Pq.rear)
return 1;
else
return 0;
}
void BFS(int(* G)[10], int* visit, int N, int V) {
visit[V] = 1;
printf("%d ", V);
Enquee(V);
while(!IsEmpty()) {
V = Dequee(); //以下遍历V的临接点
for (int i = 0; i < N; i++) {
//遍历每个临接点 对某个点的临接点来说,要按下三角矩阵遍历列
if (G[i][V] == 1 && visit[i] != 1) {
visit[i] = 1;
printf("%d ", i);
Enquee(i);
}
}
}
}
int main() {
int N, E;
int a1, a2;
scanf("%d %d", &N, &E);
int G[10][10];
for (int i = 0; i < E; i++) {
scanf("%d %d", &a1, &a2);
G[a1][a2] = 1;
G[a2][a1] = 1;
}
//for (int i = 0; i < 44; i++) {
// printf("%d ", G[i]);
//}
int visit[10];
for (int i = 0; i < N; i++) {
visit[i] = 0;
}
for (int i = 0; i < N; i++) {
if (visit[i] == 0) {
printf("{ ");
DFS(G, visit, N, i);
printf("}\n");
}
}
for (int i = 0; i < N; i++) {
visit[i] = 0;
}
for (int i = 0; i < N; i++) {
if (visit[i] == 0) {
printf("{ ");
BFS(G, visit, N, i);
printf("}\n");
}
}
}