迷宫求解_栈的应用

#ifndef STACK_FOR_MAZE_H
#define STACK_FOR_MAZE_H  

#include <stdbool.h>  

struct Node;
typedef struct Node * Stack; //用于声明指向表头的指针   
typedef struct Node * PtrToNode; //用于声明指向结构体(节点)的指针   
typedef int ElementType;

struct Node
{
	ElementType row;//行号,从0开始
	ElementType column;//列号,从0开始
	PtrToNode next;//前一个节点(元素)地址
};

/*********函数声明********/

//创建一个空栈,返回表头地址  
Stack InitStack(void);
//判断是否为空 空返回true 
bool IsEmpty(Stack S);  
// 出栈 返回新栈顶地址  
void Pop(Stack S);
//清空栈 变为空栈   
void ClearStack(Stack S);
//返回栈中元素数目 
int StackLength(Stack S);
//返回行号的值 
ElementType GetRow(Stack S);
//返回列号的值
ElementType GetColumn(Stack S);
// 入栈 返回新栈顶地址
void Push(ElementType _row, ElementType _column, Stack S);

#endif


#include <stdio.h>
#include <stdlib.h>
#include "stackformaze.h"

Stack InitStack(void)
{
	Stack tempNode;
	tempNode = (PtrToNode)malloc(sizeof(struct Node));
	if (tempNode == NULL)
		printf("Out of space!\n");
	tempNode->next = NULL;
	return tempNode;
}

bool IsEmpty(Stack S)
{
	return S->next == NULL;
}

void Pop(Stack S)
{// 出栈 返回新栈顶地址  
	PtrToNode tempNode;
	if (IsEmpty(S)){
		printf("Stack is empty\n");
	}
	else{
		tempNode = S->next;
		S->next = S->next->next; //S为表头地址,表头的next存的是栈顶的地址   
		free(tempNode); //栈底元素的next为NULL 所以在删除最后一个元素后   
	}
}

void ClearStack(Stack S)
{
	while (IsEmpty(S) != true)
		Pop(S);
}

int StackLength(Stack S)
{
	int sum = 0;
	while (IsEmpty(S) != true){
		S->next = S->next->next;
		sum++;
	}
	return sum;
}

ElementType GetRow(Stack S)
{
	if (IsEmpty(S)){
		printf("Stack is empty\n");
		return 0; //返回值防止编译器报错   
	}
	else
		return S->next->row;
}

ElementType GetColumn(Stack S)
{
	if (IsEmpty(S)){
		printf("Stack is empty\n");
		return 0; //返回值防止编译器报错   
	}
	else
		return S->next->column;
}

void Push(ElementType _row, ElementType _column, Stack S)
{
	PtrToNode tempNode;
	tempNode = (PtrToNode)malloc(sizeof(struct Node));
	if (tempNode == NULL){
		printf("Out Of Space!\n");
	}
	else{
		tempNode->next = S->next;
		tempNode->row = _row;
		tempNode->column = _column;
		S->next = tempNode;
	}
}


#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include "stackformaze.h"
//迷宫复杂度,越大,迷宫没有出口的概率越大,详情见initMaze函数
#define COMPLEXITY 3

typedef struct coordinate{
	int maze[20][20];
	int flag[400];//标记某点是否有路可走,1表示有,0表示没有,与二维数组的数据关系为index = i * size + j
}Maze;

void initMaze(Maze &M, int size);

int main()
{
	int size = 10;//迷宫的尺寸size * size,size不能大于20,不能小于5
	Maze myMaze;//迷宫二维数组
	Stack stepForMaze = InitStack();//记录正确路线坐标
	initMaze(myMaze, size);
	int tempRow;//当前所在行号
	int tempCol;//当前所在列号
	
	Push(1, 1, stepForMaze);//起点录入

	//未到终点且栈不为空则继续循环
	printf("探索过程为:\n");
	while ((GetRow(stepForMaze) != size - 2 || GetColumn(stepForMaze) != size - 2) && !IsEmpty(stepForMaze)){
		tempRow = GetRow(stepForMaze);//当前所在行号
		tempCol = GetColumn(stepForMaze);//当前所在列号
		myMaze.flag[tempRow * size + tempCol] = 0;//标记该点来过了,防止通过Pop以外的方式回退
		
		printf("(%d,", tempRow);
		printf("%d) -> ", tempCol);

		if (myMaze.maze[tempRow][tempCol + 1] == 0 && myMaze.flag[tempRow * size + tempCol + 1] == 1)
			Push(tempRow, tempCol + 1, stepForMaze);
		else if (myMaze.maze[tempRow + 1][tempCol] == 0 && myMaze.flag[(tempRow + 1) * size + tempCol] == 1)
			Push(tempRow + 1, tempCol, stepForMaze);
		else if (myMaze.maze[tempRow][tempCol - 1] == 0 && myMaze.flag[tempRow * size + tempCol - 1] == 1)
			Push(tempRow, tempCol - 1, stepForMaze);
		else if (myMaze.maze[tempRow - 1][tempCol] == 0 && myMaze.flag[(tempRow - 1) * size + tempCol] == 1)
			Push(tempRow - 1, tempCol, stepForMaze);
		else{
			Pop(stepForMaze);//四个方向都走不通则出栈
		}
	}

	printf("\n");

	if (IsEmpty(stepForMaze)){
		printf("迷宫没有出路!\n");
	}
	else{
		printf("最终得出的可行路径为:\n");
		while (!IsEmpty(stepForMaze)){
			printf("(%d,", GetRow(stepForMaze));
			printf("%d) <- ", GetColumn(stepForMaze));
			Pop(stepForMaze);
		}
	}

	system("pause");
}

//生成一个size *size大小的迷宫并输出,包括四周墙壁,size不能大于20,不能小于5
void initMaze(Maze &M,int size)
{
	srand((int)time(0));

	if (size > 20 || size < 5){
		printf("size不能大于20,不能小于5!\n");
		exit(-1);
	}

	for (int i = 0; i < size; i++){//初始化四周的墙壁
		if (i == 0 || i == size - 1){
			for (int j = 0; j < size; j++){
				M.maze[i][j] = 1;
				M.flag[i * size + j] = 1;
			}
		}
		else{
			M.maze[i][0] = 1;
			M.maze[i][size - 1] = 1;
			M.flag[i * size + 0] = 1;
			M.flag[i * size + size - 1] = 1;

		}
	}

	for (int i = 1; i < size - 1; i++){//利用随机数初始化迷宫
		for (int j = 1; j < size - 1; j++){//保证起点附近四个单位为0
			if ((i == 1 && j == 1) || (i == 1 && j == 2) ||
				(i == 2 && j == 1) || (i == 2 && j == 2)){
				M.maze[i][j] = 0;
				M.flag[i * size + j] = 1;
			}
			else if (i == size - 2 && j == size - 2){//保证终点为空
				M.maze[i][j] = 0;
				M.flag[i * size + j] = 1;
			}
			else{//如此处理使得0出现的概率大于1
				int temp = rand() % 10;
				if (temp > COMPLEXITY){
					M.maze[i][j] = 0;
					M.flag[i * size + j] = 1;
				}
				else{
					M.maze[i][j] = 1;
					M.flag[i * size + j] = 1;
				}
			}
		}
	}

	for (int i = 0; i < size; i++){//打印迷宫
		for (int j = 0; j < size; j++){
			printf("%d ", M.maze[i][j]);
		}
		printf("\n");
	}
}



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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值