算法學習(2):BFS/DFS-廣度優先/深度優先

DFS
  • 思想:一直往深處走,直到找到目標或者走不下去爲止。通常用遞歸來實現
  • 使用棧保存未被遍歷的結點,結點按照深度優先的次序被訪問並被壓入棧中,並以相反的次序出棧
  • 應用:走迷宮,查找環路,查找聯通區域
BFS
  • 思想:先遍歷所有的兄弟節點再遍歷子節點,按層遍歷。通常用隊列來實現
  • 使用隊列保存未被檢測的結點。結點按照廣度優先的次序被訪問和進出隊列
  • 應用:找最短的路徑,或者到一個目標最短要幾步

下面以走迷宮爲例分別用DFS與BFS判斷能否從迷宮的起始點走到終點
DFS
#include <stdio.h>    
int o[4][2] = { { 1, 0 }, { 0, 1 }, { -1, 0 }, { 0, -1 } };
int map[10][10] = {0};
int minStep = 100;
int stack[100][2] = {0};
int step = 0;
int minStack[100][2] = {0};
void DFS(int sY, int sX, int eY, int eX)
{
	if (step >= minStep)return;
	if (map[sY][sX] == 0)return;
	stack[step][0] = sY;
	stack[step++][1] = sX;
	map[sY][sX] = 0;
	if ((sY == eY) && (sX == eX))
	{
		if (minStep > step)
		{
			minStep = step;
			for (int i = 0; i < step; i++)
			{
				minStack[i][0] = stack[i][0];
				minStack[i][1] = stack[i][1];
			}
		}
		map[sY][sX] = 1;
		step--;
		return;
	}
	for (int i = 0; i < 4; i++)
	{
		(DFS(sY + o[i][0], sX + o[i][1], eY, eX));
	}

	map[sY][sX] = 1;
	step--;
	return;
}

int main(int argc, char** argv)
{
	freopen("input.txt", "r", stdin);
	int N;
	scanf("%d\n", &N);
	for (int case_num = 0; case_num < N; case_num++)
	{
		for (int i = 1; i <= 8; i++)
		{
			for (int j = 1; j <= 8; j++)
			{
				scanf("%d\n", &map[i][j]);
			}
			scanf("\n");
		}
	}

	DFS(1,1,8,8);
	printf("%d\n", minStep-1);
	for (int i = 0; i < minStep; i++)
	{
		printf("%d %d\n", minStack[i][0], minStack[i][1]);
	}
	//if (ret)printf("success\n");
	//else printf("failed\n");
}
BFS
#include <stdio.h>
int o[4][2] = { { 1, 0 }, { 0, 1 }, { -1, 0 }, { 0, -1 } };
int map[10][10] = { 0 };
int queue[100][2] = {0};
int front = 0;
int back = 0;
int parent[10][10][2] = {0};

void BFS(int sY, int sX, int eY, int eX)
{
	queue[back][0] = sY;
	queue[back++][1] = sX;
	map[sY][sX] = 1;
	while (front < back)
	{
		int Y = queue[front][0];
		int X = queue[front][1];
		for (int i = 0; i < 4; i++)
		{
			int newY = Y + o[i][0];
			int newX = X + o[i][1];
			if (map[newY][newX] == 0)continue;
			if (map[newY][newX] > (map[Y][X] + 1))
			{
				map[newY][newX] = map[Y][X] + 1;
				parent[newY][newX][0] = Y;
				parent[newY][newX][1] = X;
				if ((newY == eY) && (newX == eX))
				{
					return;
				}
				queue[back][0] = newY;
				queue[back++][1] = newX;
			}
		}
		front++;
	}
}
int main(int argc, char** argv)
{
	freopen("input.txt", "r", stdin);
	int N;
	scanf("%d\n", &N);
	for (int case_num = 0; case_num < N; case_num++)
	{
		for (int i = 1; i <= 8; i++)
		{
			for (int j = 1; j <= 8; j++)
			{
				scanf("%d\n", &map[i][j]);
				if (map[i][j] == 1)map[i][j] = 100;//100 代表走過的
			}
			scanf("\n");
		}
	}

	BFS(1, 1, 8, 8);
	if (map[8][8] == 100)printf("failed\n");
	else printf("%d\n", map[8][8]);

	int x = 8, y = 8;
	int stack[100][2] = {0};
	int step = 0;
	while (x > 0 || y > 0)
	{
		stack[step][0] = y;
		stack[step++][1] = x;
		int newY = parent[y][x][0];
		int newX = parent[y][x][1];
		x = newX;
		y = newY;
	}
	for (int i = step - 1; i >= 0; i--)
	{
		printf("%d %d\n", stack[i][0], stack[i][1]);
	}
}


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章