Java迷宫问题回溯栈_迷宫问题--压栈、回溯、全部路径、最短路径

#pragma once

#include

#include

#include

#include

#include

#define MAX_ 100

#define ROW 6

#define COL 6

//坐标结构体

typedef struct Pos

{

int x;

int y;

}Pos;

//坐标,当前位置状态

typedef struct Arg

{

Pos pos;

int att;

}Arg;

//栈

typedef struct Stack

{

Arg arr[MAX_];

int size;

}Stack;

void Print();

Stack stack;

//迷宫

int gMaze[ROW][COL] = {

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

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

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

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

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

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

};

//保存每次路径的指针数组

int *gSuccess[ROW*COL];

int gSize = 0;

//保存最短路径的指针

int *min = NULL;

int k = 0;

//定义一个符号数组来代替迷宫的1,2,3,4,5,6,

//看起来能直观一点

static const char *symbols[] = {

"█",

"",

"←",

"↑",

"→",

"↓",

"◇"

};

//初始化栈

void Init(Stack *stack)

{

assert(stack);

stack->arr[stack->size].pos.x = 0;

stack->arr[stack->size].pos.y = 0;

stack->arr[stack->size].att = 0;

stack->size = 0;

}

//压栈

void Push(Stack *stack, Arg arg, int att)

{

assert(stack);

assert(stack->size < MAX_);

stack->arr[stack->size].pos.x = arg.pos.x;

stack->arr[stack->size].pos.y = arg.pos.y;

stack->arr[stack->size].att = att;

stack->size++;

}

//出栈

void Pop(Stack *stack)

{

assert(stack);

assert(stack->size >0);

stack->size--;

}

//初始化

void Destroy(Stack *stack)

{

assert(stack);

stack->size = 0;

}

//栈大小

int Size(Stack *stack)

{

return stack->size;

}

//栈是否为空

int IsEmpty(Stack *stack)

{

return stack->size == 0 ? 1 : 0;

}

//栈顶元素

Arg Top(Stack *stack)

{

return stack->arr[stack->size-1];

}

//此位置是否通行

int CheckIsAccess(int x, int y)

{

if (gMaze[x][y] == 1)

{

return 1;

}

else {

return 0;

}

}

//清屏,并且改变数组值为当前位置状态

void SetAndPrint(int x,int y, int att)

{

system("cls");

gMaze[x][y] = att;

Print(gMaze);

Sleep(50);

}

//改变栈内,当前坐标状态

void UpdateTop(Stack *stack, int data)

{

stack->arr[stack->size-1].att = data;

}

//打印

void Print(int (*gMaze)[COL])

{

int i, j;

for (i = 0; i < ROW; i++)

{

for (j = 0; j < COL; j++)

{

printf("%s", symbols[gMaze[i][j]] );

}

printf("\n");

}

}

//主循环体

void GoMazeRecirsion(Pos pos)

{

Arg arg;

Arg argnext;

arg.pos = pos;

arg.att = 2;

Push(&stack, arg, 2);

while (!IsEmpty(&stack))

{

arg = Top(&stack);

if (arg.pos.y == COL - 1)

{

SetAndPrint(arg.pos.x, arg.pos.y, 6);

//开辟一块内存保存每次的数组

int *copy = (int *)malloc(sizeof(int)*COL*ROW);

assert(copy);

memcpy(copy, gMaze, sizeof(int)*COL*ROW);

gSuccess[gSize++] = copy;

//开辟一块内存用来保存最短路径

int *MIN = (int *)malloc(sizeof(int)*COL*ROW);

assert(MIN);

if(k==0 || Size(&stack) < k)

{

memcpy(MIN, gMaze, sizeof(int)*COL*ROW);

min = MIN;

k = Size(&stack);

}

}

argnext = arg;

//左边能不能走

if (argnext.att <= 2)

{

SetAndPrint(arg.pos.x, arg.pos.y, 2);

argnext = arg;

argnext.pos.y -= 1;

if (argnext.pos.y >= 0 && CheckIsAccess(argnext.pos.x, argnext.pos.y))

{

UpdateTop(&stack, 3);

Push(&stack, argnext, 2);

continue;

}

}

//上边能不能走

if (argnext.att <= 3)

{

SetAndPrint(arg.pos.x, arg.pos.y, 3);

argnext = arg;

argnext.pos.x -= 1;

if (argnext.pos.x >= 0 && CheckIsAccess(argnext.pos.x, argnext.pos.y))

{

UpdateTop(&stack, 4);

Push(&stack, argnext, 2);

continue;

}

}

//右边能不能走

if (argnext.att <= 4)

{

SetAndPrint(arg.pos.x, arg.pos.y, 4);

argnext = arg;

argnext.pos.y += 1;

if (argnext.pos.y <= COL - 1 && CheckIsAccess(argnext.pos.x, argnext.pos.y))

{

UpdateTop(&stack, 5);

Push(&stack, argnext, 2);

continue;

}

}

//下边能不能走

if (argnext.att <= 5)

{

SetAndPrint(arg.pos.x, arg.pos.y, 5);

argnext = arg;

argnext.pos.x += 1;

if (argnext.pos.x <= ROW - 1 && CheckIsAccess(argnext.pos.x, argnext.pos.y))

{

UpdateTop(&stack, 6);

Push(&stack, argnext, 2);

continue;

}

}

gMaze[arg.pos.x][arg.pos.y] = 1;

Pop(&stack);

}

printf("没有通路了\n");

}

//主函数体

void test()

{

int i;

Init(&stack);

Pos pos = {5, 2};

GoMazeRecirsion(pos);

printf("有%d种方法\n",gSize);

for (i = 0; i < gSize; i++)

{

Print((int(*)[COL])gSuccess[i]);

}

printf("最短路径\n");

Print((int(*)[COL])min);

//别忘记释放内存

for (i = 0; i < gSize; i++)

{

free(gSuccess[i]);

}

free(min);

min = NULL;

gSuccess[gSize] = NULL;

system("pause");

}

#include "MIGONG.h"

//主函数

int main()

{

test();

return 0;

}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值