回溯和遞迴實現迷宮問題(C語言)

great_beauty發表於2020-11-15

前言

學完圖的資料結構,發現可以藉助其遍歷思想實現迷宮問題,遂用兩種方法編寫實現。

本文章僅展示標頭檔案、測試檔案以及遞迴函式的定義,鼓勵大家開動腦筋,自行補充回溯演算法。至於其他函式的實現,可以在文末下載。


題目背景

用nm的矩陣表述迷宮,位置(0,0)表示入口,(n,m)表示出口,n和m分別代表迷宮的行數和列數。迷宮中的每個位置都可以用其行號和列號來指定。在矩陣中,當且僅當一個位置(x,y)處有障礙時,其值為‘ * ’ , 否則其值為‘ ’。


題目要求

尋找一條從入口<0,0>到出口<5,5>的路徑
用遞迴和回溯兩個求解方案分別實現


演算法思想

遞迴實現
在這裡插入圖片描述
回溯實現
在這裡插入圖片描述


標頭檔案

#ifndef MAZE_PROBLEM_H
#define MAZE_PROBLEM_H
#include <stdio.h>
#include<stdbool.h>

#define MAXSIZE 6
//路口結構體定義
struct InterSection {
	int i;//行號
	int j;//列號
	int right;//可走的方位號
} InterSection[MAXSIZE];
void MyPath(char maze[][MAXSIZE], int moved[][MAXSIZE]);

/*順序表結構體,用於輔助遞迴函式*/

typedef struct
{
	int list[50][2];
	int size;
}SeqList;
void ListInitiate(SeqList* L);
bool ListInsert(SeqList* L, int x, int y);
bool ListDelete(SeqList* L);
int ListOutput(SeqList* L);
bool RecursMaze(char maze[][MAXSIZE], int moved[][MAXSIZE], SeqList* L, int i, int j);

#endif // !MAZE_PROLBLEM_H


測試函式

int main() {
	//迷宮陣列
	char maze[MAXSIZE][MAXSIZE] = {
		{' ',' ',' ',' ','*',' '},
		{' ','*','*','*',' ',' '},
		{' ',' ','*',' ',' ','*'},
		{'*',' ',' ',' ','*',' '},
		{'*','*',' ','*','*',' '},
		{'*','*',' ',' ',' ',' '},
	};
	//記錄是否已訪問的陣列
	int moved[MAXSIZE][MAXSIZE] = { 0 };
	//MyPath(maze, moved);
	SeqList	MyTest;
	ListInitiate(&MyTest);
	RecursMaze(maze, moved,&MyTest ,0, 0);
	ListOutput(&MyTest);
}

遞迴函式

#include "MazeProblem.h"
//遞迴實現
bool RecursMaze(char maze[][MAXSIZE], int moved[][MAXSIZE], SeqList* L,int i, int j) {
	if (i < 0 || j < 0 || i >= MAXSIZE || j >= MAXSIZE||moved[i][j]==1)return false;
	if ((i == MAXSIZE - 1) && (j == MAXSIZE - 1))return true;
	if (maze[i][j] == '*')return false;
	moved[i][j] = 1;
	ListInsert(L, i, j);
	if (RecursMaze(maze, moved,L, i-1, j))return true;
	if (RecursMaze(maze, moved,L, i, j+1))return true;
	if (RecursMaze(maze, moved,L, i+1, j))return true;
	if (RecursMaze(maze, moved,L, i, j-1))return true;
	ListDelete(L);
	return false;
}


下載地址:

連結: https://github.com/clolrful/Maze-problem.git.

相關文章