C 언어로 배우는 DFS 기반 미로 탐색 알고리즘

DFS(깊이 우선 탐색)는 그래프 탐색 알고리즘 중 하나로, 주어진 문제의 해를 찾기 위해 특정 경로를 끝까지 탐색한 후 돌아오는 방식으로 작동합니다. 본 기사에서는 DFS를 활용해 미로를 탐색하는 알고리즘을 C 언어로 구현하고, 이를 단계별로 설명합니다. 미로 탐색 문제는 데이터 구조와 알고리즘의 핵심 개념을 배우기에 적합하며, 실습을 통해 이론과 코드를 모두 익힐 수 있는 주제입니다. C 언어 초보자부터 알고리즘에 관심 있는 개발자까지, 본 기사를 통해 DFS와 미로 탐색의 원리를 깊이 이해할 수 있습니다.

목차

DFS와 미로 탐색의 기본 개념


DFS(깊이 우선 탐색)는 그래프나 트리의 각 노드를 최대한 깊게 탐색한 후, 더 이상 갈 곳이 없으면 이전 노드로 되돌아오는 방식으로 작동하는 알고리즘입니다. 이 알고리즘은 주로 재귀 함수 또는 스택을 사용해 구현됩니다.

DFS 알고리즘의 원리


DFS는 다음의 과정을 반복하여 문제를 해결합니다.

  1. 현재 노드를 방문 처리합니다.
  2. 방문하지 않은 인접 노드가 있으면 그 노드를 탐색합니다.
  3. 더 이상 인접 노드가 없을 경우, 이전 노드로 돌아갑니다(백트래킹).

미로 탐색에서의 DFS 적용


DFS는 미로 탐색 문제에서 매우 유용하게 사용됩니다. 미로를 2차원 배열로 표현하고, 각 칸을 그래프의 노드로 간주하여 시작점에서 목표 지점까지의 경로를 탐색합니다.

  • 시작점: 탐색을 시작하는 미로의 위치입니다.
  • 목표 지점: 탐색이 종료되는 미로의 위치입니다.
  • 장애물: 이동이 불가능한 칸으로, DFS 탐색의 경로에서 제외됩니다.

DFS의 장점과 한계

  • 장점: 모든 가능한 경로를 탐색할 수 있으므로, 해를 반드시 찾을 수 있습니다(단, 해가 존재할 경우).
  • 한계: 경로의 깊이가 매우 깊어지면 메모리 오버플로우가 발생할 가능성이 있습니다.

DFS의 기본 원리와 미로 탐색에의 응용 방법을 이해하면, 복잡한 그래프 탐색 문제도 단계적으로 해결할 수 있습니다.

C 언어에서의 DFS 구현

DFS를 C 언어로 구현하기 위해서는 재귀 함수 또는 스택을 사용하여 탐색 과정을 코드로 표현할 수 있습니다. 아래는 재귀 함수를 활용한 DFS의 기본 구현 예제입니다.

DFS 함수의 구조


DFS 함수는 다음과 같은 구조를 가집니다.

  1. 현재 노드를 방문 처리합니다.
  2. 방문 가능한 모든 인접 노드에 대해 DFS를 호출합니다.
  3. 탐색이 완료되면 호출 스택에서 제거됩니다.

기본 DFS 코드 예제

#include <stdio.h>
#define SIZE 5

// 방문 여부를 저장하는 배열
int visited[SIZE] = {0};

// 그래프를 인접 행렬로 표현
int graph[SIZE][SIZE] = {
    {0, 1, 1, 0, 0},
    {1, 0, 0, 1, 1},
    {1, 0, 0, 1, 0},
    {0, 1, 1, 0, 1},
    {0, 1, 0, 1, 0}
};

// DFS 함수
void dfs(int node) {
    printf("%d ", node);
    visited[node] = 1; // 현재 노드 방문 처리

    for (int i = 0; i < SIZE; i++) {
        if (graph[node][i] == 1 && !visited[i]) {
            dfs(i); // 인접 노드에 대해 재귀 호출
        }
    }
}

int main() {
    printf("DFS 탐색 순서: ");
    dfs(0); // 0번 노드부터 탐색 시작
    return 0;
}

코드 설명

  • graph 배열: 그래프를 인접 행렬로 표현하여 노드 간의 연결 관계를 정의합니다.
  • visited 배열: 이미 방문한 노드를 추적하여 중복 탐색을 방지합니다.
  • dfs 함수: 현재 노드를 출력한 후, 인접 노드에 대해 재귀적으로 탐색을 진행합니다.
  • main 함수: 탐색을 시작할 노드를 지정하고 DFS를 호출합니다.

출력 결과


위 코드를 실행하면 다음과 같은 탐색 순서를 출력합니다(그래프 구성에 따라 다를 수 있음).

DFS 탐색 순서: 0 1 3 4 2

확장 가능성


위 코드는 기본적인 DFS 구조를 보여줍니다. 이를 미로 탐색 문제에 맞게 확장하려면, 미로를 표현할 데이터 구조와 추가 조건을 구현하면 됩니다. 이는 이후 단계에서 다룹니다.

미로 데이터 구조 설계

미로 탐색 알고리즘을 구현하려면 미로를 효과적으로 표현할 데이터 구조가 필요합니다. 일반적으로 2차원 배열을 사용하여 미로를 설계합니다. 배열의 각 칸은 다음과 같은 요소를 표현합니다.

미로의 구성 요소

  1. 0: 이동 가능한 경로
  2. 1: 장애물(벽)
  3. S: 시작점
  4. E: 목표 지점

미로를 표현하는 2차원 배열


미로의 각 위치를 숫자로 표현한 예는 다음과 같습니다.

#include <stdio.h>
#define ROWS 5
#define COLS 5

// 미로 데이터
int maze[ROWS][COLS] = {
    {0, 1, 0, 0, 0},
    {0, 1, 0, 1, 0},
    {0, 0, 0, 1, 0},
    {0, 1, 1, 1, 0},
    {0, 0, 0, 0, 0}
};

미로 데이터 구조의 특성

  1. 경로와 장애물 구분: 값이 0인 칸은 이동 가능하며, 값이 1인 칸은 이동이 불가능합니다.
  2. 배열의 경계 처리: 미로의 경계선을 벗어나는 경우를 고려하여 탐색 로직을 작성해야 합니다.
  3. 시작점과 목표 지점의 정의: 미로 탐색 알고리즘의 입력으로 시작점과 목표 지점을 전달합니다.
   int startX = 0, startY = 0; // 시작점
   int endX = 4, endY = 4;     // 목표 지점

미로 데이터 구조 설계의 주요 고려사항

  • 입출력 형식: 사용자로부터 미로 데이터를 입력받거나 파일에서 불러오는 기능을 추가할 수 있습니다.
  • 동적 크기: 고정된 배열 대신 동적 할당을 사용하면 더 큰 크기의 미로를 처리할 수 있습니다.
  int** maze = malloc(rows * sizeof(int*));
  for (int i = 0; i < rows; i++) {
      maze[i] = malloc(cols * sizeof(int));
  }
  • 확장 가능성: 이동 가능한 칸에 가중치나 다른 특성을 부여해 더욱 복잡한 문제를 해결할 수 있습니다.

미로의 시각적 표현


미로를 직관적으로 표시하려면 출력 형식을 조정합니다.

void printMaze(int maze[ROWS][COLS]) {
    for (int i = 0; i < ROWS; i++) {
        for (int j = 0; j < COLS; j++) {
            printf("%d ", maze[i][j]);
        }
        printf("\n");
    }
}

출력 예시

0 1 0 0 0  
0 1 0 1 0  
0 0 0 1 0  
0 1 1 1 0  
0 0 0 0 0  

이 데이터 구조를 기반으로, DFS 알고리즘을 통해 미로 탐색을 수행할 수 있습니다. 다음 단계에서는 이를 활용한 경로 탐색 알고리즘을 설명합니다.

경로 탐색 알고리즘

DFS를 활용하여 미로에서 시작점부터 목표 지점까지의 경로를 탐색하는 알고리즘을 구현합니다. 이 과정에서는 이동 가능한 경로를 탐색하고, 경로가 막히면 되돌아가는 방식(백트래킹)을 사용합니다.

경로 탐색 로직


경로 탐색은 다음 단계를 포함합니다.

  1. 현재 위치를 방문 처리합니다.
  2. 네 방향(상, 하, 좌, 우)으로 이동할 수 있는지 확인합니다.
  3. 이동 가능한 경우, 해당 방향으로 이동하고 재귀적으로 탐색을 이어갑니다.
  4. 목표 지점에 도달하면 탐색을 종료합니다.
  5. 모든 방향이 막힌 경우, 이전 위치로 되돌아갑니다(백트래킹).

코드 구현

#include <stdio.h>
#define ROWS 5
#define COLS 5

// 미로 데이터
int maze[ROWS][COLS] = {
    {0, 1, 0, 0, 0},
    {0, 1, 0, 1, 0},
    {0, 0, 0, 1, 0},
    {0, 1, 1, 1, 0},
    {0, 0, 0, 0, 0}
};

// 방문 여부를 저장하는 배열
int visited[ROWS][COLS] = {0};

// 방향 배열 (상, 하, 좌, 우)
int dx[4] = {-1, 1, 0, 0};
int dy[4] = {0, 0, -1, 1};

// 경로 탐색 함수
int dfs(int x, int y, int endX, int endY) {
    // 현재 위치 출력
    printf("(%d, %d) ", x, y);

    // 목표 지점 도달
    if (x == endX && y == endY) {
        return 1;
    }

    // 현재 위치 방문 처리
    visited[x][y] = 1;

    // 네 방향으로 이동
    for (int i = 0; i < 4; i++) {
        int newX = x + dx[i];
        int newY = y + dy[i];

        // 유효한 이동인지 확인
        if (newX >= 0 && newX < ROWS && newY >= 0 && newY < COLS // 미로 경계를 벗어나지 않음
            && maze[newX][newY] == 0 // 이동 가능한 칸
            && !visited[newX][newY]) { // 아직 방문하지 않음

            if (dfs(newX, newY, endX, endY)) { // 목표 지점까지 경로 발견
                return 1;
            }
        }
    }

    // 되돌아가기 (백트래킹)
    visited[x][y] = 0;
    return 0;
}

int main() {
    int startX = 0, startY = 0; // 시작점
    int endX = 4, endY = 4;     // 목표 지점

    printf("탐색 경로: ");
    if (dfs(startX, startY, endX, endY)) {
        printf("\n경로 탐색 성공\n");
    } else {
        printf("\n경로를 찾을 수 없습니다\n");
    }

    return 0;
}

코드 설명

  1. visited 배열: 각 칸이 방문되었는지 추적하여 중복 탐색을 방지합니다.
  2. dxdy 배열: 상, 하, 좌, 우 네 방향으로의 이동을 표현합니다.
  3. dfs 함수: 재귀적으로 경로를 탐색하며, 목표 지점에 도달하면 탐색을 종료합니다.
  4. 백트래킹: 잘못된 경로를 되돌아가며 다른 경로를 탐색할 수 있게 합니다.

출력 예시

탐색 경로: (0, 0) (1, 0) (2, 0) (2, 1) (2, 2) (3, 2) (4, 2) (4, 3) (4, 4) 
경로 탐색 성공

확장 가능성

  • 최단 경로 탐색: 경로의 길이를 비교하여 가장 짧은 경로를 찾는 로직을 추가할 수 있습니다.
  • 가중치 포함: 특정 칸에 가중치를 부여하여 경로 선택 시 영향을 미치게 할 수 있습니다.

이 코드를 기반으로, DFS와 백트래킹을 활용한 경로 탐색의 핵심 개념을 학습할 수 있습니다.

백트래킹 활용 방법

백트래킹은 DFS 탐색에서 잘못된 경로를 되돌아가며 올바른 경로를 찾는 데 사용되는 기법입니다. 미로 탐색에서 백트래킹은 막다른 길을 만났을 때 이전 경로로 돌아가 다른 경로를 탐색할 수 있도록 합니다.

백트래킹의 원리

  1. 현재 위치에서 다음으로 이동할 수 있는 경로를 탐색합니다.
  2. 이동 가능한 경로가 없거나 목표 지점에 도달하지 못한 경우, 현재 위치를 방문하지 않은 상태로 되돌립니다.
  3. 이전 위치로 돌아가 다른 경로를 탐색합니다.

코드에서 백트래킹의 구현


DFS 탐색 함수에서 백트래킹은 다음과 같이 구현됩니다.

  1. 현재 위치를 방문 처리한 후 탐색을 진행합니다.
  2. 네 방향 중 모든 경로가 막혔거나 탐색이 실패한 경우, 방문 상태를 원래대로 복원합니다.

백트래킹 코드 예시

int dfs(int x, int y, int endX, int endY) {
    // 현재 위치 출력
    printf("(%d, %d) ", x, y);

    // 목표 지점 도달
    if (x == endX && y == endY) {
        return 1; // 탐색 성공
    }

    // 현재 위치 방문 처리
    visited[x][y] = 1;

    // 네 방향으로 이동
    for (int i = 0; i < 4; i++) {
        int newX = x + dx[i];
        int newY = y + dy[i];

        // 유효한 이동인지 확인
        if (newX >= 0 && newX < ROWS && newY >= 0 && newY < COLS // 미로 경계를 벗어나지 않음
            && maze[newX][newY] == 0 // 이동 가능한 칸
            && !visited[newX][newY]) { // 아직 방문하지 않음

            if (dfs(newX, newY, endX, endY)) { // 재귀 호출
                return 1; // 탐색 성공
            }
        }
    }

    // 백트래킹 (방문 상태 복원)
    visited[x][y] = 0;
    return 0; // 탐색 실패
}

백트래킹의 핵심

  1. 방문 상태 복원: 탐색이 실패한 경우, 현재 위치를 방문하지 않은 상태로 복원하여 다른 경로를 탐색할 수 있게 합니다.
   visited[x][y] = 0;
  1. 재귀 호출 구조: 모든 경로를 깊이 탐색한 후 되돌아오는 구조로 작동합니다.

실행 결과


미로가 아래와 같을 때 백트래킹이 작동하는 방식:

0 1 0 0 0  
0 1 0 1 0  
0 0 0 1 0  
0 1 1 1 0  
0 0 0 0 0  

DFS 탐색 경로:

(0, 0) (1, 0) (2, 0) (2, 1) (2, 2) (3, 2) (4, 2) (4, 3) (4, 4) 

만약 목표 지점에 도달할 수 없는 경우, 백트래킹을 통해 다른 모든 가능한 경로를 탐색한 뒤 실패를 반환합니다.

백트래킹의 장점

  • 효율적인 경로 탐색: 불필요한 경로를 빠르게 포기하고 다른 경로를 탐색합니다.
  • 문제 해결 능력: 경로가 복잡한 문제에서도 모든 가능한 해를 탐색할 수 있습니다.

확장 가능성

  • 최적화된 경로 탐색: 백트래킹과 함께 비용(가중치)을 고려하면 최적 경로를 탐색하는 알고리즘으로 확장 가능합니다.
  • 다중 목표 탐색: 여러 목표 지점이 있는 경우에도 동일한 기법을 적용할 수 있습니다.

백트래킹은 미로 탐색과 같은 문제를 해결하는 데 필수적인 알고리즘 설계 기법입니다. 이를 통해 탐색 과정의 유연성과 효율성을 높일 수 있습니다.

예외 처리와 경계 조건

미로 탐색 알고리즘을 설계할 때, 탐색 과정에서 발생할 수 있는 예외 상황과 경계 조건을 처리해야 안정적이고 효율적인 코드 구현이 가능합니다. 예외 처리는 프로그램의 오류 방지뿐 아니라, 경계 상황에서도 정상적으로 작동하도록 보장합니다.

미로 탐색에서의 주요 예외 상황

  1. 미로 경계를 벗어나는 경우
  • 탐색 위치가 미로의 범위를 넘어가는 경우입니다.
  • 처리 방법: 경계를 확인하여 유효한 위치인지 검사합니다.
  1. 장애물(벽)에 도달하는 경우
  • 이동하려는 칸이 1로 표시된 경우입니다.
  • 처리 방법: 이동 가능한 칸(0)인지 확인합니다.
  1. 이미 방문한 위치를 다시 방문하는 경우
  • 중복 탐색으로 무한 루프가 발생할 수 있습니다.
  • 처리 방법: visited 배열을 사용하여 방문 여부를 기록합니다.
  1. 목표 지점이 없는 경우
  • 목표 지점이 정의되지 않거나 도달할 수 없는 경우입니다.
  • 처리 방법: 탐색 실패 시 적절한 메시지를 반환합니다.

코드에서의 예외 처리


다음은 주요 예외 처리를 포함한 탐색 함수 코드입니다.

int dfs(int x, int y, int endX, int endY) {
    // 경계 조건 확인
    if (x < 0 || x >= ROWS || y < 0 || y >= COLS) {
        return 0; // 미로 범위를 벗어남
    }

    // 장애물 및 방문 여부 확인
    if (maze[x][y] == 1 || visited[x][y]) {
        return 0; // 이동 불가능한 칸 또는 이미 방문한 위치
    }

    // 목표 지점 도달
    if (x == endX && y == endY) {
        printf("목표 지점 도달: (%d, %d)\n", x, y);
        return 1;
    }

    // 현재 위치 방문 처리
    visited[x][y] = 1;

    // 네 방향 탐색
    for (int i = 0; i < 4; i++) {
        int newX = x + dx[i];
        int newY = y + dy[i];

        if (dfs(newX, newY, endX, endY)) {
            return 1; // 경로 탐색 성공
        }
    }

    // 백트래킹 (방문 상태 복원)
    visited[x][y] = 0;
    return 0; // 경로 탐색 실패
}

경계 조건 검증

  1. 미로 경계 처리
   if (x < 0 || x >= ROWS || y < 0 || y >= COLS) {
       return 0;
   }

이 코드는 탐색 위치가 미로의 범위를 벗어나지 않도록 보장합니다.

  1. 장애물 및 방문 상태 확인
   if (maze[x][y] == 1 || visited[x][y]) {
       return 0;
   }

탐색하려는 칸이 이동 가능한지와 중복 방문 여부를 확인합니다.

출력 결과: 경계 조건 및 예외 상황


미로가 아래와 같을 때, 장애물과 경계 조건을 올바르게 처리한 결과를 확인할 수 있습니다.

0 1 0 0 0  
0 1 0 1 0  
0 0 0 1 0  
0 1 1 1 0  
0 0 0 0 0  

탐색 경로:

(0, 0) (1, 0) (2, 0) (2, 1) (2, 2) (3, 2) (4, 2) (4, 3) (4, 4) 
목표 지점 도달: (4, 4)

확장 가능성

  • 비정형 미로 처리: 미로가 불완전하거나 동적일 때, 예외 처리를 강화합니다.
  • 에러 메시지 추가: 조건이 충족되지 않을 경우 사용자에게 명확한 경고를 제공합니다.

미로 탐색에서 예외 상황과 경계 조건을 제대로 처리하면, 알고리즘이 다양한 환경에서도 안정적으로 작동할 수 있습니다.

전체 코드 예제

앞서 설명한 미로 데이터 구조, DFS 탐색, 예외 처리, 백트래킹 등을 통합하여 미로 탐색의 전체 코드를 작성합니다. 이 코드는 C 언어로 구현되며, 시작점에서 목표 지점까지의 경로를 찾습니다.

전체 코드

#include <stdio.h>
#include <stdlib.h>

#define ROWS 5
#define COLS 5

// 미로 데이터
int maze[ROWS][COLS] = {
    {0, 1, 0, 0, 0},
    {0, 1, 0, 1, 0},
    {0, 0, 0, 1, 0},
    {0, 1, 1, 1, 0},
    {0, 0, 0, 0, 0}
};

// 방문 여부를 저장하는 배열
int visited[ROWS][COLS] = {0};

// 방향 배열 (상, 하, 좌, 우)
int dx[4] = {-1, 1, 0, 0};
int dy[4] = {0, 0, -1, 1};

// DFS 함수
int dfs(int x, int y, int endX, int endY) {
    // 경계 조건 확인
    if (x < 0 || x >= ROWS || y < 0 || y >= COLS) {
        return 0; // 미로 범위를 벗어남
    }

    // 장애물 및 방문 여부 확인
    if (maze[x][y] == 1 || visited[x][y]) {
        return 0; // 이동 불가능한 칸 또는 이미 방문한 위치
    }

    // 현재 위치 출력
    printf("(%d, %d) ", x, y);

    // 목표 지점 도달
    if (x == endX && y == endY) {
        return 1; // 탐색 성공
    }

    // 현재 위치 방문 처리
    visited[x][y] = 1;

    // 네 방향 탐색
    for (int i = 0; i < 4; i++) {
        int newX = x + dx[i];
        int newY = y + dy[i];

        if (dfs(newX, newY, endX, endY)) { // 재귀 호출
            return 1; // 경로 탐색 성공
        }
    }

    // 백트래킹 (방문 상태 복원)
    visited[x][y] = 0;
    return 0; // 경로 탐색 실패
}

// 미로 출력 함수
void printMaze() {
    for (int i = 0; i < ROWS; i++) {
        for (int j = 0; j < COLS; j++) {
            printf("%d ", maze[i][j]);
        }
        printf("\n");
    }
}

int main() {
    int startX = 0, startY = 0; // 시작점
    int endX = 4, endY = 4;     // 목표 지점

    printf("미로:\n");
    printMaze();

    printf("\n탐색 경로: ");
    if (dfs(startX, startY, endX, endY)) {
        printf("\n경로 탐색 성공: 목표 지점 (%d, %d)에 도달\n", endX, endY);
    } else {
        printf("\n경로를 찾을 수 없습니다.\n");
    }

    return 0;
}

코드 설명

  1. maze 배열: 미로를 2차원 배열로 표현합니다.
  2. visited 배열: 방문한 위치를 기록하여 중복 탐색을 방지합니다.
  3. dfs 함수: 재귀적으로 경로를 탐색하며, 목표 지점에 도달하면 성공을 반환합니다.
  4. 백트래킹 구현: 잘못된 경로는 방문 상태를 복원하고 다른 경로를 탐색합니다.
  5. printMaze 함수: 미로의 현재 상태를 출력합니다.

실행 결과


입력 미로가 아래와 같을 때:

0 1 0 0 0  
0 1 0 1 0  
0 0 0 1 0  
0 1 1 1 0  
0 0 0 0 0  

프로그램 출력:

미로:
0 1 0 0 0  
0 1 0 1 0  
0 0 0 1 0  
0 1 1 1 0  
0 0 0 0 0  

탐색 경로: (0, 0) (1, 0) (2, 0) (2, 1) (2, 2) (3, 2) (4, 2) (4, 3) (4, 4) 
경로 탐색 성공: 목표 지점 (4, 4)에 도달

확장 가능성

  • 동적 미로 생성: 사용자 입력을 통해 미로를 동적으로 생성하도록 구현할 수 있습니다.
  • 최단 경로 탐색: 경로의 길이를 비교하여 최단 경로를 찾는 기능을 추가할 수 있습니다.

이 코드는 DFS와 백트래킹을 활용한 미로 탐색의 모든 핵심 요소를 포함하며, 다양한 응용 문제로 확장 가능합니다.

실행 결과와 테스트 케이스

미로 탐색 코드를 실행한 결과와 다양한 테스트 케이스를 확인하여 알고리즘이 올바르게 작동하는지 검증합니다. 각 테스트 케이스는 미로의 구조와 시작점 및 목표 지점의 위치를 다양화하여 코드의 안정성을 평가합니다.

테스트 케이스 1: 기본 미로


미로 구조:

0 1 0 0 0  
0 1 0 1 0  
0 0 0 1 0  
0 1 1 1 0  
0 0 0 0 0  
  • 시작점: (0, 0)
  • 목표 지점: (4, 4)

출력:

탐색 경로: (0, 0) (1, 0) (2, 0) (2, 1) (2, 2) (3, 2) (4, 2) (4, 3) (4, 4)  
경로 탐색 성공: 목표 지점 (4, 4)에 도달

테스트 케이스 2: 막다른 길이 있는 미로


미로 구조:

0 1 0 0 0  
0 1 1 1 0  
0 0 0 1 0  
1 1 1 1 0  
0 0 0 0 0  
  • 시작점: (0, 0)
  • 목표 지점: (4, 4)

출력:

탐색 경로: (0, 0) (1, 0) (2, 0) (2, 1) (2, 2) (3, 2) (4, 2) (4, 3) (4, 4)  
경로 탐색 성공: 목표 지점 (4, 4)에 도달

테스트 케이스 3: 목표 지점이 없는 경우


미로 구조:

0 1 0 0 0  
0 1 0 1 0  
0 0 0 1 0  
1 1 1 1 1  
0 0 0 0 0  
  • 시작점: (0, 0)
  • 목표 지점: (4, 4)

출력:

탐색 경로: (0, 0) (1, 0) (2, 0) (2, 1) (2, 2)  
경로를 찾을 수 없습니다.

테스트 케이스 4: 큰 크기의 미로


미로 구조:

0 0 0 0 1 0 0  
1 1 1 0 1 0 1  
0 0 0 0 0 0 0  
0 1 1 1 1 1 0  
0 0 0 0 0 0 0  
  • 시작점: (0, 0)
  • 목표 지점: (4, 6)

출력:

탐색 경로: (0, 0) (0, 1) (0, 2) (0, 3) (1, 3) (2, 3) (2, 4) (2, 5) (2, 6) (3, 6) (4, 6)  
경로 탐색 성공: 목표 지점 (4, 6)에 도달

테스트 케이스 5: 비정형 미로


미로 구조:

0 1 0 1 0  
1 0 1 0 1  
0 0 0 1 0  
1 0 1 0 1  
0 0 0 0 0  
  • 시작점: (0, 0)
  • 목표 지점: (4, 4)

출력:

탐색 경로: (0, 0) (1, 1) (2, 2) (3, 3) (4, 4)  
경로 탐색 성공: 목표 지점 (4, 4)에 도달

결론

  • 성공적인 탐색: 모든 테스트 케이스에서 DFS 알고리즘이 정상적으로 작동하여 목표 지점에 도달합니다.
  • 예외 처리 확인: 막다른 길이나 비정형 미로에서도 올바르게 작동하여 오류가 발생하지 않습니다.
  • 확장 가능성: 다양한 미로 크기와 구조에서도 코드가 안정적으로 작동합니다.

테스트를 통해 코드가 미로 탐색 문제를 정확히 해결함을 확인할 수 있습니다. 다음 단계에서는 코드 최적화나 추가 기능을 논의할 수 있습니다.

요약

DFS(깊이 우선 탐색)를 활용한 미로 탐색 알고리즘을 C 언어로 구현하는 방법을 다뤘습니다. 미로를 2차원 배열로 표현하고, DFS와 백트래킹을 통해 시작점에서 목표 지점까지의 경로를 탐색하는 과정을 설명했습니다. 또한, 경계 조건과 예외 상황을 처리하는 방법과 실행 결과를 다양한 테스트 케이스를 통해 검증했습니다. 이 알고리즘은 미로 탐색 문제뿐만 아니라 다양한 그래프 탐색 문제에도 확장 가능하며, 기본적인 프로그래밍 및 알고리즘 학습에 유용한 사례입니다.

목차