1. 程式人生 > >棧與佇列的應用——迷宮問題

棧與佇列的應用——迷宮問題

在熟悉了棧的基本操作之後,本人試著解決了迷宮問題過程如下:

再次用的是回溯法解決。具體想了解去百度!!!!!

首先在標頭檔案裡定義了三種不同難度迷宮程式碼如下:

#pragma once

#include "Stack.h"

#define N 6
//static int maze[N][N] = {
//	{0,0,0,0,0,0},
//	{0,0,1,0,0,0},
//	{0,0,1,0,0,0},
//	{0,0,1,1,1,0},
//	{0,0,1,0,1,1},
//	{0,0,1,0,0,0},
//};

//static int maze[N][N] = {
//	{0,0,0,0,0,0},
//	{0,0,1,1,1,1},
//	{0,0,1,0,0,0},
//	{0,0,1,1,1,1},
//	{0,0,1,0,0,0},
//	{0,0,1,0,0,0},
//};

static int maze[N][N] = {
	{0,0,0,0,0,0},
	{0,0,1,1,1,0},
	{0,0,1,0,1,0},
	{0,0,1,1,1,1},
	{0,0,1,0,0,0},
	{0,0,1,0,0,0},
};


int GetMazePath(Pos entry, Pos exit);
void PrintMaze();

void TestMaze();

分別是:

一、只有一個出口的迷宮

二、含有多個出口的迷宮

三、帶環的迷宮

首先先列出前倆種迷宮的程式碼:

#include "Maze.h"

int CheckAccess(Pos next)
{
	if (next._row >= 0 && next._row < N
		&& next._col >= 0 && next._col < N
		&& maze[next._row][next._col] == 1)
	{
		return 1;
	}
	else
	{
		return 0;
	}
}

Stack minpath;
int pathsize = 0;

int GetMazePath(Pos entry, Pos exit)
{
	Stack path;
	StackInit(&path);
	StackPush(&path, entry);

	while (StackEmpty(&path))
	{
		Pos cur = StackTop(&path);
		Pos next;

		maze[cur._row][cur._col] = 2;
		//if (cur._row == exit._row
		//	&& cur._col == exit._col)
		if (cur._col == 5)//‘標記行’
		{
			// 出口

			// 如果只找一條通路,則返回
			//StackDestory(&path);
			//return 1;
			//若要解決第一類迷宮問題,將上面註釋取消且將’標記行‘註釋即可
			if(pathsize == 0 
				|| StackSize(&path) < pathsize)
			{
				pathsize = StackSize(&path);
			}

		}
		
		// 探測下一個可以去的位置

		// 上
		next = cur;
		next._row -= 1;
		if (CheckAccess(next))
		{
			StackPush(&path, next);
			continue;
		}

		// 下
		next = cur;
		next._row += 1;
		if (CheckAccess(next))
		{
			StackPush(&path, next);
			continue;
		}
		
		// 左
		next = cur;
		next._col -= 1;
		if (CheckAccess(next))
		{
			StackPush(&path, next);
			continue;
		}

		// 右
		next = cur;
		next._col += 1;
		if (CheckAccess(next))
		{
			StackPush(&path, next);
			continue;
		}

		// 回溯
		StackPop(&path);
	}

	return 0;
}

void PrintMaze()
{
	size_t  i, j;
	for (i = 0; i < N; ++i)
	{
		for (j = 0; j < N; ++j)
		{
			printf("%d ", maze[i][j]);
		}
		printf("\n");
	}

	printf("\n");
}

void TestMaze()
{
	Pos entry, exit;
	entry._row = 5;
	entry._col = 2;

	exit._row = 4;
	exit._col = 5;

	PrintMaze();

	printf("是否有出口?:%d\n", GetMazePath(entry, exit));
	printf("最短路徑:%d\n", pathsize);

	PrintMaze();
}

void main()
{
	TestMaze();
}

下面是第三類帶環迷宮程式碼:

#include "Maze.h"

int CheckAccess(Pos cur, Pos next)
{
	if ((next._row >= 0 && next._row < N && next._col >= 0 && next._col < N)
		&& (maze[next._row][next._col] == 1 || maze[next._row][next._col] > maze[cur._row][cur._col] + 1))
	{
		return 1;
	}
	else
	{
		return 0;
	}
}

Stack minpath;
int pathsize = 0;

int GetMazePath(Pos entry, Pos exit)
{
	Stack path;
	StackInit(&path);
	StackPush(&path, entry);

	maze[entry._row][entry._col] = 2;

	while (StackEmpty(&path))
	{
		Pos cur = StackTop(&path);
		Pos next;
	
		if (cur._col == 5)
		{
			if(pathsize == 0 
				|| StackSize(&path) < pathsize)
			{
				pathsize = StackSize(&path);
			}

		}

		// 探測下一個可以去的位置

		// 上
		next = cur;
		next._row -= 1;
		if (CheckAccess(cur, next))
		{
			maze[next._row][next._col] = maze[cur._row][cur._col]+1;
			StackPush(&path, next);
			continue;
		}

		// 下
		next = cur;
		next._row += 1;
		if (CheckAccess(cur, next))
		{
			maze[next._row][next._col] = maze[cur._row][cur._col]+1;
			StackPush(&path, next);
			continue;
		}

		// 左
		next = cur;
		next._col -= 1;
		if (CheckAccess(cur, next))
		{
			maze[next._row][next._col] = maze[cur._row][cur._col]+1;
			StackPush(&path, next);
			continue;
		}

		// 右
		next = cur;
		next._col += 1;
		if (CheckAccess(cur, next))
		{
			maze[next._row][next._col] = maze[cur._row][cur._col]+1;
			StackPush(&path, next);
			continue;
		}

		// 回溯
		StackPop(&path);
	}

	return 0;
}

void PrintMaze()
{
	size_t  i, j;
	for (i = 0; i < N; ++i)
	{
		for (j = 0; j < N; ++j)
		{
			printf("%d ", maze[i][j]);
		}
		printf("\n");
	}

	printf("\n");
}

void TestMaze()
{
	Pos entry, exit;
	entry._row = 5;
	entry._col = 2;

	exit._row = 4;
	exit._col = 5;

	PrintMaze();

	printf("是否有出口?:%d\n", GetMazePath(entry, exit));
	printf("最短路徑:%d\n", pathsize);

	PrintMaze();
}

void main()
{
	TestMaze();
}

在此附上迷宮所需棧的程式碼:

//標頭檔案------------------------------------------------------------------------------------


#pragma once

#include <stdio.h>
#include <malloc.h>
#include <assert.h>
#include <stdlib.h>

//typedef int DataType;
//
//#define N 10
//typedef struct Stack
//{
//	DataType _a[N];
//	int _top; // 棧頂
//}Stack;

typedef struct Pos
{
	int _row;
	int _col;
}Pos;


typedef Pos DataType;


typedef struct Stack
{
	DataType* _a;
	int _top;		// 棧頂
	int _capacity;  // 容量 
}Stack;




void StackInit(Stack* ps);
void StackDestory(Stack* ps);

void StackPush(Stack* ps, DataType x);
void StackPop(Stack* ps);
DataType StackTop(Stack* ps);
int StackEmpty(Stack* ps);
int StackSize(Stack* ps);
void StackPrint(Stack * ps);


void TestStack();


----------------------------------------------------------------------------------------

函式檔案---------------------------------------------------------------------------------


#include "Stack.h"

void StackInit(Stack* ps)
{
	assert(ps);
	ps->_a = (DataType*)malloc(sizeof(DataType));
	assert(ps->_a);
	ps->_top = 0;
	ps->_capacity = 1;
}

void StackDestory(Stack* ps)
{	
	assert(ps);
	if(ps->_a)
	{
		free(ps->_a);
		ps->_a = NULL;
		ps->_top = 0;
		ps->_capacity = 0;
	}
}


void StackPush(Stack* ps,DataType x)
{
	assert(ps);
	if(ps->_top == ps->_capacity)
	{
		ps->_a = realloc(ps->_a,2*ps->_capacity*sizeof(DataType));
		ps->_capacity *= 2;
	}
	ps->_a[ps->_top] = x;
	ps->_top++;
}

void StackPop(Stack* ps)
{
	assert(ps->_a);
	assert(ps->_top > 0);
	ps->_top--;
}

DataType StackTop(Stack* ps)
{
	assert(ps->_a && ps->_top > -1);
	return ps->_a[ps->_top-1];
}

//空   0
//非空 1
int StackEmpty(Stack* ps)
{
	assert(ps);
	return ps->_top == 0 ? 0 :1;
}

int StackSize(Stack* ps)
{
	return ps->_top;
}

void StackPrint(Stack *ps)
{
	int i;
	if(ps->_top == 0)
	{
		printf("棧為空,無法列印\n");
		return ;
	}
	printf("棧內容為:");
    for(i=ps->_top-1;i>=0;i--)
	{
        printf("%d ",ps->_a[i]);
    }
	printf("\n");
}


----------------------------------------------------------------------------------------

程式碼為練習所做,如有錯誤,還請指出!!在此謝過!!