java使用回溯法迷宫问题,第十一章--迷宫问题-回溯法

// 第十一章--迷宫问题(二).cpp : 定义控制台应用程序的入口点。

//

#include "stdafx.h"

#include

using namespace std;

enum

StatusCode{SUCCESS,FAIL,UNDER_FLOW,OVER_FLOW,RANGE_ERROR,DUPLICATE_ERROR,NOT_PRESENT,ENTRY_INSERTED,ENTRY_FOUND,VISITED,UNVISITED};//状态码

// 结点类模板

template

struct Node

{

// 数据成员:

ElemType

data; //

数据域

Node

*next; // 指针域

// 构造函数模板:

Node(); //

无参数的构造函数模板

Node(ElemType item,

Node *link =

NULL); // 已知数据元素值和指针建立结构

};

// 结点类模板的实现部分

template

Node::Node()

// 操作结果:构造指针域为空的结点

{

next = NULL;

}

template

Node::Node(ElemType item,

Node *link)

// 操作结果:构造一个数据域为item和指针域为link的结点

{

data = item;

next = link;

}

// 链队列类模板

template

class LinkQueue

{

protected:

// 链队列实现的数据成员:

Node

*front,

*rear; //

队头队尾指指

// 辅助函数模板:

void

Init(); //

初始化队列

public:

// 抽象数据类型方法声明及重载编译系统默认方法声明:

LinkQueue(); //

无参数的构造函数模板

virtual

~LinkQueue(); //

析构函数模板

int Length()

const; //

求队列长度 bool Empty()

const; //

判断队列是否为空

void

Clear(); //

将队列清空

void Traverse(void (*visit)(const ElemType

&)) const ; // 遍历队列

StatusCode OutQueue(ElemType

&e); //

出队操作

StatusCode GetHead(ElemType &e)

const; //

取队头操作

StatusCode InQueue(const ElemType

&e); //

入队操作

LinkQueue(const

LinkQueue

&copy); //

复制构造函数模板

LinkQueue

&operator =(const

LinkQueue

&copy);// 重载赋值运算符

};

// 链队列类模板的实现部分

template

void

LinkQueue::Init()

// 操作结果:初始化队列

{

rear = front = new

Node; //

生成头结点

}

template

LinkQueue::LinkQueue()

// 操作结果:构造一个空队列

{

Init();

}

template

LinkQueue::~LinkQueue()

// 操作结果:销毁队列

{

Clear(); }

template

int LinkQueue::Length()

const

//

操作结果:返回队列长度 {

int count =

0; // 计数器

for (Node

*tmpPtr = front->next; tmpPtr != NULL; tmpPtr =

tmpPtr->next)

{ // 用tmpPtr依次指向每个元素

count++; //

对栈每个元素进行计数

}

return count;

}

template

bool LinkQueue::Empty()

const

// 操作结果:如队列为空,则返回true,否则返回false

{

return rear == front;

}

template

void

LinkQueue::Clear()

// 操作结果:清空队列

{

ElemType tmpElem; // 临时元素值

while (Length() > 0)

{ // 队列非空,则出列

OutQueue(tmpElem);

}

}

template

void

LinkQueue::Traverse(void

(*visit)(const ElemType &)) const

// 操作结果:依次对队列的每个元素调用函数(*visit)

{

for (Node

*tmpPtr = front->next; tmpPtr != NULL;

tmpPtr =

tmpPtr->next)

{ // 对队列每个元素调用函数(*visit)

(*visit)(tmpPtr->data);

}

}

template

StatusCode

LinkQueue::OutQueue(ElemType

&e)

// 操作结果:如果队列非空,那么删除队头元素,并用e返回其值,返回SUCCESS,

// 否则返回UNDER_FLOW,

{

if (!Empty())

{ // 队列非空

Node

*tmpPtr = front->next; //

指向队列头素

e =

tmpPtr->data; //

用e返回队头元素

front->next =

tmpPtr->next; //

front指向下一元素

if (rear == tmpPtr)

{ //

表示出队前队列中只有一个元素,出队后为空队列

rear =

front;

}

delete

tmpPtr; //

释放出队的结点

return SUCCESS;

}

else

{ // 队列为空

return UNDER_FLOW;

}

}

template

StatusCode

LinkQueue::GetHead(ElemType

&e) const

// 操作结果:如果队列非空,那么用e返回队头元素,返回SUCCESS,

// 否则返回UNDER_FLOW,

{

if (!Empty())

{ // 队列非空

Node

*tmpPtr = front->next; //

指向队列头素

e =

tmpPtr->data; //

用e返回队头元素

return SUCCESS;

}

else

{ // 队列为空

return UNDER_FLOW;

}

}

template

StatusCode

LinkQueue::InQueue(const

ElemType &e)

// 操作结果:插入元素e为新的队尾,返回SUCCESS

{

Node

*tmpPtr = new

Node(e); //

生成新结点

rear->next =

tmpPtr; //

新结点追加在队尾

rear =

tmpPtr; //

rear指向新队尾

return SUCCESS;

}

template

LinkQueue::LinkQueue(const

LinkQueue

&copy)

// 操作结果:由队列copy构造新队列——复制构造函数模板

{

Init();

for (Node

*tmpPtr = copy.front->next; tmpPtr != NULL;

tmpPtr =

tmpPtr->next)

{ //

对copy队列每个元素对当前队列作入队列操作

InQueue(tmpPtr->data);

}

}

template

LinkQueue

&LinkQueue::operator

=(const LinkQueue

&copy)

// 操作结果:将队列copy赋值给当前队列——重载赋值运算符

{

if (&copy != this)

{

Clear();

for

(Node *tmpPtr =

copy.front->next; tmpPtr != NULL;

tmpPtr =

tmpPtr->next)

{ //

对copy队列每个元素对当前队列作入队列操作

InQueue(tmpPtr->data);

}

}

return *this;

}

// 链栈类模板

template

class LinkStack

{

protected:

// 链栈实现的数据成员:

Node

*top; //

栈顶指针

// 辅助函数模板:

void

Init(); //

初始化栈

public:

// 抽象数据类型方法声明及重载编译系统默认方法声明:

LinkStack(); //

无参数的构造函数模板

virtual

~LinkStack(); //

析构函数模板

int Length()

const; //

求栈长度 bool Empty()

const; //

判断栈是否为空

void

Clear(); //

将栈清空

void Traverse(void (*visit)(const ElemType

&)) const ; //

遍历栈

StatusCode Push(const ElemType

&e); //

入栈

StatusCode Top(ElemType &e)

const; //

返回栈顶元素

StatusCode Pop(ElemType

&e); //

出栈

LinkStack(const

LinkStack

&copy); //

复制构造函数模板

LinkStack

&operator =(const

LinkStack

&copy); // 重载赋值运算符

};

// 链栈类模板的实现部分

template

void

LinkStack::Init()

// 操作结果:初始化栈

{

top =

NULL; //

构造栈顶指针

}

template

LinkStack::LinkStack()

// 操作结果:构造一个空栈表

{

Init();

}

template

LinkStack::~LinkStack()

// 操作结果:销毁栈

{

Clear();

}

template

int LinkStack::Length()

const

// 操作结果:返回栈元素个数

{

int count =

0; // 计数器

for (Node

*tmpPtr = top; tmpPtr != NULL; tmpPtr =

tmpPtr->next)

{ // 用tmpPtr依次指向每个元素

count++; //

对栈每个元素进行计数

}

return count;

}

template

bool LinkStack::Empty()

const

// 操作结果:如栈为空,则返回true,否则返回false

{

return top == NULL;

}

template

void

LinkStack::Clear()

// 操作结果:清空栈

{

ElemType tmpElem; // 临时元素值

while (!Empty())

Pop(tmpElem);

}

template

void

LinkStack::Traverse(void

(*visit)(const ElemType &)) const

// 操作结果:从栈底到栈顶依次对栈的每个元素调用函数(*visit)

{

Node

*tmpPtr; LinkStack

tmpS; // 临时栈,tmpS中元素顺序与当前栈元素顺序相反

for (tmpPtr = top; tmpPtr != NULL; tmpPtr =

tmpPtr->next)

{ // 用tmpPtr依次指向当前栈的每个元素

tmpS.Push(tmpPtr->data); //

对当前栈的每个元素入栈到tmpS中

}

for (tmpPtr = tmpS.top; tmpPtr != NULL; tmpPtr =

tmpPtr->next)

{ //

用tmpPtr从栈顶到栈底依次指向栈tmpS的每个元素

(*visit)(tmpPtr->data); //

对栈tmpS的每个元素调用函数(*visit)

}

}

template

StatusCode

LinkStack::Push(const

ElemType &e)

// 操作结果:将元素e追加到栈顶,如成功则返加SUCCESS,否则如动态内存已耗尽

// 将返回OVER_FLOW

{

Node

*new_top = new Node(e,

top);

if (new_top == NULL)

{ // 动态内存耗尽

return OVER_FLOW;

}

else

{ // 操作成功

top = new_top;

return SUCCESS;

}

}

template

StatusCode

LinkStack::Top(ElemType

&e) const

// 操作结果:如栈非空,用e返回栈顶元素,返回SUCCESS,否则返回UNDER_FLOW

{

if(Empty())

{ // 栈空

return UNDER_FLOW;

}

else

{ // 栈非空,操作成功

e =

top->data; //

用e返回栈顶元素

return SUCCESS;

}

}

template

StatusCode

LinkStack::Pop(ElemType

&e)

// 操作结果:如栈非空,删除栈顶元素,并用e返回栈顶元素,返回SUCCESS,否则

// 返回UNDER_FLOW

{

if (Empty())

{ // 栈空

return UNDER_FLOW;

}

else

{ // 操作成功

Node

*old_top = top; // 旧栈顶

e =

old_top->data; //

用e返回栈顶元素

top =

old_top->next; //

top指向新栈顶

delete

old_top; //

删除旧栈顶

return SUCCESS;

}

}

template

LinkStack::LinkStack(const

LinkStack

&copy)

// 操作结果:由栈copy构造新栈——复制构造函数模板

{

if (copy.Empty())

{ // copy为空

Init(); //

构造一空栈

}

else

{ // copy非空,复制栈

top = new

Node(copy.top->data); //

生成当前栈项

Node

*buttomPtr =

top; //

当前栈底指针

for

(Node *tmpPtr =

copy.top->next; tmpPtr != NULL; tmpPtr =

tmpPtr->next)

{ //

用tmpPtr依次指向其余元素

buttomPtr->next

= new

Node(tmpPtr->data);

// 向栈底追加元素 buttomPtr =

buttomPtr->next; //

buttomPtr指向新栈底

}

}

}

template

LinkStack

&LinkStack::operator

= (const LinkStack

&copy)

// 操作结果:将栈copy赋值给当前栈——重载赋值运算符

{

if (&copy != this)

{

if (copy.Empty())

{ //

copy为空

Init(); //

构造一空栈

}

else

{ //

copy非空,复制栈

Clear(); //

清空当前栈

top = new

Node(copy.top->data); //

生成当前栈项

Node

*buttomPtr =

top; //

当前栈底指针

for

(Node *tmpPtr =

copy.top->next; tmpPtr != NULL; tmpPtr =

tmpPtr->next)

{ //

用tmpPtr依次指向其余元素

buttomPtr->next

= new

Node(tmpPtr->data);

// 向栈底追加元素 buttomPtr

=

buttomPtr->next; //

buttomPtr指向新栈底

}

}

}

return *this;

}

// 矩阵类模板

template

class Matrix

{

protected:

// 矩阵的数据成员:

ElemType

*elems; // 存储知阵元素

int rows,

cols; //

矩阵行数和列数

public:

// 抽象数据类型方法声明及重载编译系统默认方法声明:

Matrix(int rs, int cs); //

构造一个rs行cs列的矩阵

~Matrix(); //

析构函数模板

int GetRows() const; //

返回矩阵行数

int GetCols() const; //

返回矩阵列数

ElemType &operator()(int i, int

j); //

重载函数运算符

Matrix(const

Matrix

&copy); //

复制构造函数模板

Matrix

&operator =(const

Matrix

&copy); // 重载赋值运算符

};

// 三对角类模板的实现部分

template

Matrix::Matrix(int rs, int

cs)

// 操作结果:构造一个rs行cs列的矩阵

{

if (rs < 1

&& cs <

1) cout<

rows =

rs; //

rs为行数

cols =

cs; //

cs为列数

elems = new ElemType[rows *

cols]; // 分配存储空间

}

template

Matrix::~Matrix()

// 操作结果:释放矩阵所占用空间

{

if (elems != NULL) delete []elems;

}

template

int Matrix::GetRows()

const

// 操作结果:返回矩阵行数

{

return rows;

}

template

int Matrix::GetCols()

const

// 操作结果:返回矩阵列数

{

return cols;

}

template

ElemType

&Matrix::operator()(int

i, int j)

// 操作结果:重载函数运算符

{

if (i < 1 || i >

rows || j < 1 || j >

cols) cout<

return elems[(i - 1) * cols + j -

1]; // 返回元素

}

template

Matrix::Matrix(const

Matrix

&copy)

// 操作结果:由矩阵copy构造新矩阵——复制构造函数模板

{

rows =

copy.rows; // 复制行数

cols =

copy.cols; // 复制列数

elems = new ElemType[rows *

cols]; // 为数据元素分配存储空间

for (int i = 0; i < rows * cols;

i++)

{ // 复制数据元素值

elems[i] = copy.elems[i];

}

}

template

Matrix

&Matrix::operator

=(const Matrix

&copy)

// 操作结果:将矩阵copy赋值给当前矩阵——重载赋值运算符

{

if (&copy != this)

{

if (elems != NULL) delete

[]elems; // 释放数据元素空间

rows =

copy.rows; // 复制行数

cols =

copy.cols; // 复制列数

elems = new ElemType[rows *

cols]; // 为数据元素分配存储空间

for (int i = 0; i

< rows * cols; i++)

{ //

复制数据元素值

elems[i] =

copy.elems[i];

}

}

return *this;

}

// 迷宫单元格状态,VIA:已经过,BLOCK:阻塞(阴影),EMPTY:空

enum MazeCellStatus { EMPTY, BLOCK,VIA} ;

struct

CellType //

迷宫单元格

{

int x,

y; //

单元格的坐标

};

void OutSolution(Matrix

&mazePath, const CellType &entry,

const CellType &out); // 输出迷宫问题的解

void

MazeSolution(Matrix

&maze, int w, int h, const CellType

&entry,

const CellType &out)

// 操作结果: 求解迷宫问题

{

Matrix

mazePath(h,

w); //

迷宫路线

LinkQueue

cellQueue; //

单元格队列

CellType NullCell = {0,

0}; //

空单元格

mazePath(entry.y, entry.x) =

NullCell; //

将入口存入路径,作为路径的起始点,前驱为空

cellQueue.InQueue(entry); //

入口进队

while (!cellQueue.Empty())

{ // InQueue非空,可继续求迷宫出口

CellType

curCell; //

当前单元格

cellQueue.OutQueue(curCell); //

取出当前单元格

if (curCell.x == out.x

&& curCell.y ==

out.y) { //

已达到出口,输出解

OutSolution(mazePath,

entry, out);

return;

}

else

{

int xShift[4]

= {0, 0 , -1,

1}; //

相邻位置相对于当前位置的x相对坐标

int yShift[4]

= {-1, 1, 0,

0}; //

相邻位置相对于当前位置的y相对坐标

CellType

adjCell; //

当前位置的相邻位置

for (int i =

0; i < 4; i++)

{

adjCell.x

= curCell.x + xShift[i]; //

当前位置的相邻位置的x坐标

adjCell.y

= curCell.y + yShift[i]; //

当前位置的相邻位置的y坐标

if

(adjCell.x >= 1 &&

adjCell.x <= w &&

adjCell.y >= 1 &&

adjCell.y <= h

&&

(maze(adjCell.y, adjCell.x) == EMPTY))

{ //

相邻位置在迷宫内,并且为空白

mazePath(adjCell.y,

adjCell.x) = curCell; //

在路径上adjCell是curCell的下一个位置

maze(adjCell.y,

adjCell.x) = VIA; // 经过相邻位置

cellQueue.InQueue(adjCell); //

adjCell进队

}

}

}

}

}

void OutSolution(Matrix

&mazePath, const CellType &entry,

const CellType &out)

// 操作结果: 输出迷宫问题的解

{

LinkStack

cellStack; //

存入从出口到入口的路径上的单元格

CellType curCell =

out; //

路径上的当前单元格

cellStack.Push(curCell); //

入栈

CellType preCell = mazePath(curCell.y,

curCell.x); // 路径上curCell的上一个单元格

while (preCell.x != entry.x || preCell.y !=

entry.y)

{ // 当前单元格在路径上的上一个单元格不是入口

curCell =

preCell; //

curCell在路径上向后退一个单元格

preCell = mazePath(curCell.y,

curCell.x); // 路径上curCell的上一个单元格

cellStack.Push(curCell); //

入栈

}

cellStack.Push(entry); //

入栈

cout <<

"路径:"<

while (!cellStack.Empty())

{ // 从入口到出口输出路径

cellStack.Pop(curCell); // 出栈

cout

<< "("

<< curCell.x

<< ","

<< curCell.y

<< ")

"<

}

cout << endl;

}

int _tmain(int argc, _TCHAR* argv[])

{

const int h = 6, w =

10; //

迷宫高与宽

MazeCellStatus arrayMaze[h][w]

= // 迷宫二维数组

{ // 迷宫

{EMPTY, BLOCK, BLOCK, BLOCK,

BLOCK, BLOCK, BLOCK, BLOCK, BLOCK, BLOCK},

{EMPTY, BLOCK, EMPTY, EMPTY,

BLOCK, EMPTY, EMPTY, EMPTY, BLOCK, BLOCK},

{EMPTY, EMPTY, EMPTY, BLOCK,

BLOCK, EMPTY, BLOCK, EMPTY, EMPTY, BLOCK},

{EMPTY, BLOCK, BLOCK, EMPTY,

EMPTY, EMPTY, BLOCK, BLOCK, EMPTY, BLOCK},

{EMPTY, EMPTY, EMPTY, EMPTY,

EMPTY, EMPTY, EMPTY, EMPTY, EMPTY, BLOCK},

{BLOCK, BLOCK, BLOCK, BLOCK,

BLOCK, BLOCK, BLOCK, BLOCK, EMPTY, EMPTY} };

Matrix

maze(h, w); // 迷宫

CellType entry = {1,

1}; //

入口位置

CellType out = {10,

6}; //

出口位置

cout<

for (int r = 1; r <= h; r++)

{ // 行

for (int c = 1; c

<= w; c++)

{ // 列

maze(r, c) =

arrayMaze[r - 1][c - 1]; // 为迷宫赋初值

cout<

";

}

cout<

}

MazeSolution(maze, w, h, entry,

out); // 求解迷宫

system("PAUSE"); //

调用库函数system()

return 0;

}

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值