>第 12 章 栈与队列>深度优先搜索>习题

Brooklyn yuan15549424@gmail.com
2009-04-12 21:32:21

我先看到的广搜,又发现了这里的深搜,感觉都练习完之后有很多收获。关于几个问题,我试着做了一下。
1. 我认为用堆栈可能能够正向排序吧,没试验。
2. 我试过链表,发现不行……想如果用队列,那就跟predecessor没多少区别了。最后没辙,看到第三问……
3. 用递归实现了,没用结构,主函数很简单。只用一个visit子函数以及一个print_maze函数。

算法导论里面是用的递归,但是我做完这么多之后,发现我练习了链表,还有堆栈。

最后,发现这里是C语言教程,但是包含了许多常见的算法,还有详细图解以及习题,真的很不错。支持这个网站。


kyle zhukai1985427@163.com
2010-07-28 07:40:37

第三题:
#include <stdio.h>
#define N 5
int maze[5][5] = {
	0, 1, 0, 0, 0,
	0, 1, 0, 1, 0,
	0, 0, 0, 0, 0,
	0, 1, 0, 1, 0,
	0, 0, 0, 0, 0
};

typedef struct point {
	int row;
int col} Point;
Point stack[100];

int i = 0, count = 0;
void push(int r,int c)
{	Point p={r,c};
	stack[i] = p;
	i++;
}

Point pop()
{
	i--;
	return stack[i];
}


void dfs(int r, int c)
{
	if (r == N - 1 && c == N - 1) {
		push(r,c);
		for(int j=0;j<i;j++) {
			printf("(%d,%d)--->",stack[j].row, stack[j].col);
		}
		printf("OOO\n");
		count++;
			maze[r][c] = 0;
			pop();
	} else {

		if (r - 1 >= 0 && maze[r-1][c] == 0) {
			push(r,c);
			maze[r][c] = 2;
			dfs(r - 1, c);
			maze[r][c] = 0;
			pop();
		}
		if (c - 1 >= 0 && maze[r][c-1] == 0) {
			push(r,c);
			maze[r][c] = 2;
			dfs(r, c - 1);
			maze[r][c] = 0;
			pop();
		}
		if (r + 1 < 5 && maze[r+1][c] == 0) {
			push(r,c);
			maze[r][c] = 2;
			dfs(r + 1, c);
			maze[r][c] = 0;
			pop();
		}
		if (c + 1 < 5 && maze[r][c+1] == 0) {
			push(r,c);
			maze[r][c] = 2;
			dfs(r, c + 1);
			maze[r][c] = 0;
			pop();
		}
	}
}

int main()
{
	dfs(0, 0);
	printf("-----count:%d-----\n", count);
	return 0;
}


杨柳梧桐 iamapureman@gmail.com
2010-09-24 18:55:35

对第二个问题想了一会儿,才想到其实应该可以用1..MAX_ROW*MAX_COL个整数分别代表maze矩阵的所有元素,predecessor二维数组每个元素里面存对应其位置的一个整数就行了,呵呵,这算是一种方法吧


杨柳梧桐 iamapureman@gmail.com
2010-09-25 11:00:07

不过用这个方法的缺点在于,存储时需要计算i*MAX_COL+j,搜索结束后利用predecessor数组寻找可行路径时又要对整数取模和取商。。


William Ho hodezx@gmail.com
2011-08-13 11:33:32

/* 只要简单地将数组储存语句改为输出语句就可以输出路径
 × 使用递归解决迷宫问题
×/
#include <stdio.h>
#define MAX_LEN_STK 512
#define MAX_ROW 5
#define MAX_COL 5

int top = 0;

struct point path[MAX_LEN_STK];

struct point make_from_cor(int prow, int pcol)
{
	struct point p;
	p.row = prow;
	p.col = pcol;
	return p;
}

/* 0 means available path, 1 means wall*/
int maze[MAX_ROW][MAX_COL] = {
	0, 1, 0, 0, 0,
	0, 1, 0, 1, 0,
	0, 0, 0, 1, 0,
	0, 1, 1, 1, 0,
	0, 0, 0, 1, 0
};

void print_maze()
{
	int i, j;
	for (i = 0; i < MAX_ROW; i++)
	{
		for (j = 0; j < MAX_COL; j++)
		{
			printf("%d ", maze[i][j]);
		}
		printf("\n");
	}
	printf("*********\n");
}

int path_search(struct point p)
{
	maze[p.row][p.col] = 2;
	print_maze();

	if (p.row == MAX_ROW - 1 && p.col == MAX_COL - 1)		/* goal */
	{
		path[top++] = make_from_cor(p.row, p.col);
		return 1;
	}
	if ((p.col < MAX_COL - 1 && maze[p.row][p.col+1] == 0)
			&&	(path_search(make_from_cor(p.row, p.col+1))))
	{
		path[top++] = make_from_cor(p.row, p.col);
		return 1;
	}
	if ((p.row < MAX_ROW - 1 && maze[p.row+1][p.col] == 0)
			&&	(path_search(make_from_cor(p.row+1, p.col))))
	{
		path[top++] = make_from_cor(p.row, p.col);
		return 1;
	}
	if ((p.col > 0 && maze[p.row][p.col-1] == 0)
			&&	(path_search(make_from_cor(p.row, p.col-1))))
	{
		path[top++] = make_from_cor(p.row, p.col);
		return 1;
	}
	if ((p.row > 0 && maze[p.row-1][p.col] == 0)
			&& 	(path_search(make_from_cor(p.row-1, p.col))))
	{
		path[top++] = make_from_cor(p.row, p.col);
		return 1;
	}

	return 0;
}

void print_path()
{
	int i;
	--top;
	
	for (i = top; i >= 0; i--)
	{	
		printf("(%d, %d)\n", path[i].row, path[i].col);
	}
}

int main(void)
{
	struct point p = {0, 0};
	if (path_search(p))
	{
		printf("\nfound!\n");
		print_path();
	}
	else
		printf("\ncannot find the path.\n");
	return 0;
}



William Ho hodezx@gmail.com
2011-08-13 11:56:46

刚才貌似少了struct point的定义= =

/* 只要简单地将数组储存语句改为输出语句就可以输出路径
 * 使用递归解决迷宫问题
 */
#include <stdio.h>
#define MAX_LEN_STK 512
#define MAX_ROW 5
#define MAX_COL 5

int top = 0;

struct point
{
	int row;
	int col;
};

struct point path[MAX_LEN_STK];

struct point make_from_cor(int prow, int pcol)
{
	struct point p;
	p.row = prow;
	p.col = pcol;
	return p;
}

/* 0 means available path, 1 means wall*/
int maze[MAX_ROW][MAX_COL] = {
	0, 1, 0, 0, 0,
	0, 1, 0, 1, 0,
	0, 0, 0, 1, 0,
	0, 1, 1, 1, 0,
	0, 0, 0, 1, 0
};

void print_maze()
{
	int i, j;
	for (i = 0; i < MAX_ROW; i++)
	{
		for (j = 0; j < MAX_COL; j++)
		{
			printf("%d ", maze[i][j]);
		}
		printf("\n");
	}
	printf("*********\n");
}

int path_search(struct point p)
{
	maze[p.row][p.col] = 2;
	print_maze();

	if (p.row == MAX_ROW - 1 && p.col == MAX_COL - 1)		/* goal */
	{
		path[top++] = make_from_cor(p.row, p.col);
		return 1;
	}
	if ((p.col < MAX_COL - 1 && maze[p.row][p.col+1] == 0)
			&&	(path_search(make_from_cor(p.row, p.col+1))))
	{
		path[top++] = make_from_cor(p.row, p.col);
		return 1;
	}
	if ((p.row < MAX_ROW - 1 && maze[p.row+1][p.col] == 0)
			&&	(path_search(make_from_cor(p.row+1, p.col))))
	{
		path[top++] = make_from_cor(p.row, p.col);
		return 1;
	}
	if ((p.col > 0 && maze[p.row][p.col-1] == 0)
			&&	(path_search(make_from_cor(p.row, p.col-1))))
	{
		path[top++] = make_from_cor(p.row, p.col);
		return 1;
	}
	if ((p.row > 0 && maze[p.row-1][p.col] == 0)
			&& 	(path_search(make_from_cor(p.row-1, p.col))))
	{
		path[top++] = make_from_cor(p.row, p.col);
		return 1;
	}

	return 0;
}

void print_path()
{
	int i;
	--top;
	
	for (i = top; i >= 0; i--)
	{	
		printf("(%d, %d)\n", path[i].row, path[i].col);
	}
}

int main(void)
{
	struct point p = {0, 0};
	if (path_search(p))
	{
		printf("\nfound!\n");
		print_path();
	}
	else
		printf("\ncannot find the path.\n");
	return 0;
}



YorkCai caiyq_4831@qq.com
2011-10-30 23:25:23

很好的教程,适合初学,也适合复习,用一个简单的迷宫就能引入DFS的思想。


如果您有建设性意见,哪怕只是纠正一个错别字,也请不吝赐教,您留下的姓名和email将会出现在本书前言的致谢中。再次感谢您的宝贵意见!