写了C的练习,使用堆栈解决迷宫问题

本文介绍了一种使用栈数据结构实现的迷宫求解算法。通过递归回溯的方法,算法能够找到从起点到终点的路径。代码中详细定义了坐标、方向等概念,并实现了堆栈操作。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

前阵子学的数据结构,做了下复习。。。代码比较丑。。。求指点。

stack.h

#define TRUE 1
#define FALSE 0


typedef unsigned int COORD_TYPE ;
//坐标
typedef struct coord{
    COORD_TYPE x;
    COORD_TYPE y;
}COORD_DATA;
//堆栈节点
typedef struct stackNode{
    int index;
    COORD_DATA *coord;
    struct stackNode *next;
}STACK_NODE;
//设置方向
enum DIRECTION{
    up,down,left,right
};

void createStack();
void destructStack();
void push( COORD_DATA *c);
int pop();
COORD_DATA *top();
int isEmpty();
int checkStackExists( COORD_DATA *c);
//判断坐标是否可以行走,可以则前进
int walk(COORD_DATA *c, COORD_DATA *l);
//尝试像某个方向行走,如果不能行走 返回 FALSE
int checkNearByPos(COORD_DATA *next, COORD_DATA *c, COORD_DATA *last, enum DIRECTION dir);

void printMap();
void sigint_callback(int sig);

 

maze.c

#include <stdio.h>
#include <stdlib.h>
#include <signal.h>
#include <assert.h>
#include <memory.h>


#include "stack.h"


#define MAP_SIZE 30
#define ROAD "  "
#define BARRIER "口" 
#define WAY "*"

static STACK_NODE *stack;
static int map[][MAP_SIZE] = {
    #include "map.h"
};

int main(int argc, char** argv)
{
    int delay = 0;
    //异常退出信号
    signal(SIGINT, sigint_callback);
    //设置 当前 坐标 前面路的 坐标 和 上一次走过路的坐标
    COORD_DATA *c, *nextWay, *lastWay;
    nextWay = malloc(sizeof(COORD_DATA));
    assert(nextWay != NULL);
    //起点
    nextWay->x = 1;
    nextWay->y = 0;
    lastWay = malloc(sizeof(COORD_DATA));
    assert(lastWay != NULL);
    lastWay->x = -1;
    lastWay->y = -1;
    //创建堆栈
    createStack();
    //走进起点
    walk(nextWay, lastWay);

    while(TRUE)
    {
        delay = 0;
        printMap();
        while(delay++ < 30000000);
        c = top();
        //Win
        if(c == NULL)
        {
            printf("You Loss!\nNo Way Out!\n");
            break;
        }
        if(c->y == MAP_SIZE - 1)
        {
            printf("You Win!\nMaze Over!\n");
            break;
        }
        //尝试行走
        if(
            !checkNearByPos(nextWay, c, lastWay, up)
            && !checkNearByPos(nextWay, c, lastWay, down)
            && !checkNearByPos(nextWay, c, lastWay, left)
            && !checkNearByPos(nextWay, c, lastWay, right)
        )
        {
            //标记当前位置 不可通行
            map[c->y][c->x] = 3;
            //记录刚刚做过的坐标
            lastWay->x = c->x;
            lastWay->y = c->y;
            //出栈(后退)
            pop();
        }
    }
    free(lastWay);
    free(nextWay);
    destructStack();
    return EXIT_SUCCESS;
}


void printMap()
{
    system("clear");
    int i = 0;
    int j = 0;
    for(i = 0; i < MAP_SIZE; i++)
    {
        /*
        if(i == 0)
        {
            printf(" 0");
            for(j = 0; j < MAP_SIZE; j++)
            {
                printf("%2d", j);
            }
            printf("\n");
        }
        printf("%2d", i);
        */
        for(j = 0; j < MAP_SIZE; j++)
        {
            if(map[i][j] == 1)
            {
                printf("%s", BARRIER);
            }else if(map[i][j] == 2)
            {
                printf("%s", WAY);
            }else
            {
                printf("%s", ROAD);
            }
        }
        printf("\n");
    }
}

void sigint_callback(int sig)
{
    printf("\nMaze Over!\n");
    exit(EXIT_SUCCESS);
}


void createStack()
{
    stack = malloc(sizeof(STACK_NODE));
    assert(stack != NULL);
    stack->index = -1;
    stack->next = NULL;
    stack->coord = NULL;
}

void destructStack()
{
    while(top() != NULL)
    {
        pop();
    }
    free(stack);
}

void push( COORD_DATA *c)
{
    STACK_NODE *ns = malloc(sizeof(STACK_NODE));
    assert(ns != NULL);
    COORD_DATA *nc = malloc(sizeof(COORD_DATA));
    assert(nc != NULL);
    nc->x = c->x;
    nc->y = c->y;
    ns->next = stack;
    ns->coord = nc;
    ns->index = stack->index+1;
    stack = ns;
}

int pop()
{
    STACK_NODE *ns;
    if(!isEmpty())
    {
        return FALSE;
    }
    ns = stack;
    stack = stack->next;
    free(ns->coord);
    free(ns);
    return TRUE;
}

COORD_DATA *top()
{
    if(!isEmpty())
    {
        return NULL;
    }
    return stack->coord;
}

int isEmpty()
{
    return (stack != NULL && stack->index >= 0 && stack->coord != NULL);
}

int checkStackExists( COORD_DATA *coord)
{
    STACK_NODE *tmp;
    COORD_DATA *c;
    if(!isEmpty())
    {
        return FALSE;
    }
    tmp = stack;
    while(tmp != NULL && tmp->index >= 0)
    {
        c = tmp->coord;
        if(c->x == coord->x && c->y == coord->y)
        {
            return TRUE;
        }
        tmp = tmp->next;
    }
    return FALSE;
}

int walk(COORD_DATA *c, COORD_DATA *l)
{
    COORD_DATA *now;
    /*
    if(isEmpty())
    {
        now = top();
        printf("%d|%d|%d|%d|%d|%d|now:|%d|%d\n", c->x, c->y, checkStackExists(c), map[c->y][c->x], l->x, l->y, now->x, now->y);
    }else
    {
        printf("%d|%d|%d|%d|%d|%d\n", c->x, c->y, checkStackExists(c), map[c->y][c->x], l->x, l->y);
    }
    */
    if(
        (l->x != c->x || l->y != c->y)
        && c->x >= 0 
        && c-> y >= 0 
        && c->x < MAP_SIZE 
        && c->y < MAP_SIZE 
        && !checkStackExists(c)
        && (map[c->y][c->x] == 0 || map[c->y][c->x] == 2)
    )
    {
        //设置上一步
        if(isEmpty())
        {
            now = top();
            l->x = now->x;
            l->y = now->y;
        }
        map[c->y][c->x] = 2;
        push(c);
        return TRUE;
    }
    return FALSE;
}

int checkNearByPos(COORD_DATA *nextWay, COORD_DATA *c, COORD_DATA *lastWay, enum DIRECTION dir)
{
    switch(dir)
    {
        case up:
            nextWay->x = c->x;
            nextWay->y = c->y - 1;
        break;
        case down:
            nextWay->x = c->x;
            nextWay->y = c->y + 1;
        break;
        case left:
            nextWay->x = c->x - 1;
            nextWay->y = c->y;
        break;
        case right:
            nextWay->x = c->x + 1;
            nextWay->y = c->y;
        break;
        default:
            return FALSE;
        break;
    }
    return walk(nextWay, lastWay);
}

map.h

    {1,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1},
    {1,0,1,1,0,0,0,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,1},
    {1,0,1,1,0,1,0,1,1,1,1,1,1,1,1,1,1,1,0,1,1,1,1,1,1,1,1,1,0,1},
    {1,0,0,0,0,1,0,1,1,1,1,1,1,1,1,1,1,1,0,1,1,1,0,0,0,0,0,1,0,1},
    {1,1,1,1,1,1,0,0,0,0,1,1,1,1,1,1,1,1,0,1,1,1,0,1,1,1,0,1,0,1},
    {1,1,1,0,0,0,0,1,1,0,1,1,0,0,0,0,0,1,0,1,1,1,0,1,1,1,0,0,0,1},
    {1,1,1,0,1,1,1,1,1,0,1,1,0,1,1,1,0,1,0,1,1,1,0,1,1,1,1,1,1,1},
    {1,1,1,0,1,1,1,1,1,0,1,1,0,1,1,1,0,1,0,1,0,0,0,1,1,1,1,1,1,1},
    {1,1,1,0,1,1,1,1,1,0,1,1,0,1,1,1,0,0,0,1,0,1,1,1,1,1,1,1,1,1},
    {1,1,1,0,1,1,1,1,1,0,1,1,0,1,1,1,1,1,1,1,0,1,1,1,1,1,1,1,1,1},
    {1,1,1,0,1,1,1,1,1,0,0,0,0,1,1,1,1,1,1,1,0,1,1,1,1,1,1,1,1,1},
    {1,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,1,1,1,1,1,1,1,1,1},
    {1,0,1,0,0,0,0,1,1,1,1,1,0,0,0,0,0,0,0,1,0,0,0,0,0,0,1,1,1,1},
    {1,1,1,1,1,1,0,1,1,1,0,0,0,1,1,1,1,1,0,1,0,1,0,1,1,0,1,1,1,1},
    {1,0,0,0,0,1,0,1,1,1,0,1,1,1,1,1,1,1,0,1,0,1,0,0,1,0,1,1,1,1},
    {1,0,1,1,1,1,0,1,1,1,0,1,1,1,1,1,1,1,0,0,0,1,1,0,1,0,0,1,1,1},
    {1,0,1,0,0,0,0,1,1,1,0,0,1,1,1,0,0,0,1,1,1,1,1,0,1,1,0,1,1,1},
    {1,0,1,0,1,1,1,1,1,1,1,0,1,1,1,0,1,0,0,0,0,0,1,0,0,0,0,1,1,1},
    {1,0,0,0,1,1,1,1,1,1,1,0,1,1,1,0,1,1,1,1,1,0,1,0,1,1,1,1,1,1},
    {1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,0,0,0,1,1,1,1,1,1},
    {1,1,1,1,0,1,1,1,1,1,1,1,1,1,1,1,0,1,1,1,1,0,1,1,1,1,1,1,1,1},
    {1,1,0,0,0,1,1,0,0,0,0,1,1,1,1,1,0,0,1,1,1,0,1,1,1,1,1,1,1,1},
    {1,1,0,1,1,0,0,0,1,1,0,1,0,0,0,0,1,0,1,1,1,0,1,1,1,1,1,1,1,1},
    {1,1,0,0,0,0,1,1,0,0,0,1,0,1,1,0,1,0,1,0,0,0,1,1,1,1,1,1,1,1},
    {1,1,1,1,1,1,1,1,0,1,1,1,0,1,1,0,1,0,1,0,0,1,1,1,1,1,1,1,1,1},
    {1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,1,0,1,1,0,1,1,1,1,1,1,1,1,1},
    {1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,1,0,1,0,0,1,1,1,1,1,1,1,1,1},
    {1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,1,0,1,1,0,0,1,1,1,1,1,1,1,1},
    {1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,1,1,1,0,1,1,1,1,1,1,1,1},
    {1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,1,1,1,1,1,1,1,1}

转载于:https://www.cnblogs.com/lose/archive/2012/06/05/2536759.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值