C 数据结构:基于栈的深度优先搜索
一、实现
从“迷宫”起点走到终点并打印路径。
#include<stdio.h>
#include<stdlib.h>
#include<unistd.h>
#include<string.h>
#define MAZE_ROW 6
#define MAZE_COL 8
typedef struct point
{
int y_;
int x_;
}Point;
typedef struct node
{
Point data_;
struct node* next_;
}Node;
typedef struct stack
{
Node *top_;
}Stack;
int maze[MAZE_ROW][MAZE_COL] = {
1,1,1,1,1,1,1,1,
1,0,0,1,0,0,0,1,
1,1,0,1,0,1,1,1,
1,1,0,1,0,0,0,1,
0,0,0,0,0,1,1,1,
1,1,1,1,1,1,1,1 };
Point path[MAZE_ROW][MAZE_COL];//用来存储路径点
void initStack(Stack *stack);
void push(Stack *stack, Point data);
Point pop(Stack *stack);
int isEmpty(Stack *stack);
void destoryStack(Stack *stack);
void disMaze();
void walkRoad(int y, int x, Point tp, Stack *stack);
int main()
{
Point startPoint = { 4,0 }, endPoint = { 1,7 };//搜索的起点和终点
memset(path, 0xff, sizeof(Point)*MAZE_ROW*MAZE_COL);//将数组path里 点的值初始化为(-1,-1)
Stack s;
initStack(&s);
push(&s, startPoint);
int finishFlag = 0;//标记位 0:未找到终点出口,1:找到终点出口
while (!isEmpty(&s))
{
disMaze();
sleep(1);
printf("\033c");//清屏
Point tmpPoint = pop(&s);
maze[tmpPoint.y_][tmpPoint.x_] = 2;//2代表已经走过的路
if (maze[tmpPoint.y_ - 1][tmpPoint.x_] >= 0 && maze[tmpPoint.y_ - 1][tmpPoint.x_] == 0)//上
walkRoad(tmpPoint.y_ - 1, tmpPoint.x_, tmpPoint, &s);
if (maze[tmpPoint.y_ + 1][tmpPoint.x_]<MAZE_ROW&&maze[tmpPoint.y_ + 1][tmpPoint.x_] == 0)//下
walkRoad(tmpPoint.y_ + 1, tmpPoint.x_, tmpPoint, &s);
if (maze[tmpPoint.y_][tmpPoint.x_ - 1] >= 0 && maze[tmpPoint.y_][tmpPoint.x_ - 1] == 0)//左
walkRoad(tmpPoint.y_, tmpPoint.x_ - 1, tmpPoint, &s);
if (maze[tmpPoint.y_][tmpPoint.x_ + 1] <MAZE_COL&&maze[tmpPoint.y_][tmpPoint.x_ + 1] == 0)//右
walkRoad(tmpPoint.y_, tmpPoint.x_ + 1, tmpPoint, &s);
if (endPoint.y_ == tmpPoint.y_&&endPoint.x_ == tmpPoint.x_)
{
finishFlag = 1;
break;
}
}
if (1 == finishFlag)
{
printf("find!\n");
Point pp = endPoint;
while (-1 != pp.y_)
{
printf("(%2d,%2d)", pp.y_, pp.x_);//打印路径点坐标
pp = path[pp.y_][pp.x_];
}
putchar(10);
}
if (0 == finishFlag) printf("find none!\n");
disMaze();
destoryStack(&s);
return 0;
}
void initStack(Stack *stack)
{
stack->top_ = (Node*)malloc(sizeof(Node));
if (NULL == stack->top_)
exit(-1);
stack->top_->next_ = NULL;
}
void push(Stack *stack, Point data)
{
Node *ptr = (Node*)malloc(sizeof(Node));
if (NULL == ptr)
exit(-1);
ptr->data_ = data;
ptr->next_ = stack->top_->next_;
stack->top_->next_ = ptr;
}
Point pop(Stack *stack)
{
Node *tmp = stack->top_->next_;
Point tmpData = tmp->data_;
stack->top_->next_ = tmp->next_;
free(tmp);
tmp = NULL;
return tmpData;
}
int isEmpty(Stack *stack) { return NULL == stack->top_->next_; }
void destoryStack(Stack *stack)
{
while (!isEmpty(stack))
pop(stack);
free(stack->top_);
stack->top_ = NULL;
}
void disMaze()
{
for (int j = 0; j<MAZE_ROW; ++j)
{
for (int i = 0; i<MAZE_COL; ++i)
{
if (1 == maze[j][i]) printf("# ");//1 代表墙壁
else if (0 == maze[j][i]) printf(" ");//0 代表路
else printf("o ");//2代表已经走过的路
}
puts("");
}
}
void walkRoad(int y, int x, Point tp, Stack *stack)
{
Point p = { y,x };
push(stack, p);
path[y][x] = tp;
}