一、回溯算法简单说就是“一直向前走,碰壁就会头”。一个经典的例子是走迷宫,一直向前走,碰壁就回头。下面就看看这个“框架”(vc6.0下编译):
/**/
/
//
Application.h
#ifndef APPLICATION_H
#define
APPLICATION_H

#include
"
iostream.h
"
#include
"
Position.h
"

class
Application

...
{
protected:
friend ostream& operator << (ostream& stream, Application& app);

public:
Position generateInitialState();
bool valid (const Position &pos);
bool done (const Position &pos);
void record (const Position &pos);
void undo (const Position &pos);

class Iterator

...{
protected:
void* fieldPtr;

public:
Iterator ();
Iterator (const Position& pos);
Position operator ++ (int);
bool atEnd ();
};
}
;


#endif
/**/
///
//
BACKTRACK_H
#ifndef BACKTRACK_H
#define
BACKTRACK_H

#include
"
Application.h
"
#include
"
Position.h
"

class
BackTrack

...
{
public:
BackTrack (Application &app);
bool tryToSolve (Position& pos);
protected:
Application app;
}
;
#endif
/**/
//
//
BrackTrack.cpp
#include
"
BackTrack.h
"

BackTrack::BackTrack (Application
&
app)

...
{
this->app = app;
}

bool
BackTrack::tryToSolve (Position
&
pos)

...
{
bool success = false;

Application::Iterator itr(pos);
while (!success && !itr.atEnd())

...{
pos = itr++;
if (app.valid(pos))

...{
app.record(pos);
if (app.done(pos))
success = true;
else

...{
success = tryToSolve(pos);
if (!success)
app.undo(pos);
}
}
}
return success;
}
/**/
/////
//
main,cpp
#include
"
iostream.h
"
#include
"
string.h
"
#include
"
BackTrack.h
"
#include
"
Application.h
"
#include
"
Position.h
"

int
main()

...
{
Application app;
BackTrack b(app);

Position pStart = app.generateInitialState();
//cout<<app;
if (!app.valid(pStart))
cout << "there is no solution:" << endl;
else

...{
app.record (pStart);
if (app.done (pStart) || b.tryToSolve(pStart))
cout << "success" << endl;
else

...{
app.undo(pStart);
cout << "there is no solution" << endl;
}
}
return 0;
}
/**/
/////
//
POSITION_H
#ifndef POSITION_H
#define
POSITION_H

class
Position

...
{
protected:
int nRow;
int nColumn;

public:
Position();
Position(int nRow, int nColumn);
void SetPosition(int nRow, int nColumn);
int GetRow() const;
int GetColumn() const;
}
;

#endif
/**/
//
//
Position.cpp
#include
"
Position.h
"

Position::Position()

...
{
nRow = 0;
nColumn = 0;
}

Position::Position(
int
nRow,
int
nColumn)

...
{
this->nRow = nRow;
this->nColumn = nColumn;
}

void
Position::SetPosition(
int
nRow,
int
nColumn)

...
{
this->nRow = nRow;
this->nColumn = nColumn;
}

int
Position::GetRow()
const

...
{
return nRow;
}

int
Position::GetColumn()
const

...
{
return nColumn;
}
/**/
///
//
Application.cpp
#include
"
iostream.h
"
#include
"
Application.h
"
#include
"
Position.h
"

const
short
WALL
=
0
;
const
short
CORRIDOR
=
1
;
const
short
PATH
=
9
;
const
short
TRIED
=
2
;
const
short
ROWS
=
8
;
const
short
COLUMNS
=
13
;

short
grid[ROWS][COLUMNS]
=

...
{

...{1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1},

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

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

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

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

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

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

...{1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1},
}
;

Position posStart;
Position posFinish;



Position Application::generateInitialState()

...
{
int nRow;
int nColumn;

cout << "Please enter the start row and start column:";
cin >> nRow >> nColumn;
posStart.SetPosition(nRow, nColumn);
cout << endl;
cout << "Please enter the finish row and finish column:";
cin >> nRow >> nColumn;
cout << endl;
posFinish.SetPosition (nRow, nColumn);
return posStart;
}

bool
Application::valid(
const
Position
&
pos)

...
{
if (pos.GetRow() >= 0 && pos.GetRow() < ROWS &&
pos.GetColumn() >= 0 && pos.GetColumn() < COLUMNS &&
grid[pos.GetRow()][pos.GetColumn()] == CORRIDOR)

...{
return true;
}
return false;
}

void
Application::record(
const
Position
&
pos)

...
{
grid[pos.GetRow()][pos.GetColumn()] = PATH; //标识该点为已经在路径中
}

bool
Application::done(
const
Position
&
pos)

...
{
return posFinish.GetRow() == pos.GetRow() &&
posFinish.GetColumn() == pos.GetColumn();
}

void
Application::undo(
const
Position
&
pos)

...
{
grid[pos.GetRow()][pos.GetColumn()] = TRIED; //此路不通
}

ostream
&
operator
<<
(ostream
&
stream, Application
*
app)

...
{
for (int nRow = 0 ; nRow < ROWS ; nRow++)

...{
for (int nColumn = 0 ; nColumn < COLUMNS ; nColumn)
cout << grid[nRow][nColumn] << " ";
cout << endl;
}
return stream;
}


//
Iterztor
typedef
struct
_tagItrFields

...
{
int nRow;
int nColumn;
int nDirection;
}
ITRFIELDS,
*
LPITRFIELDS;

Application::Iterator::Iterator(
const
Position
&
pos)

...
{
LPITRFIELDS itrPtr = new ITRFIELDS;
itrPtr->nColumn = pos.GetColumn();
itrPtr->nRow = pos.GetRow();
itrPtr->nDirection = 0;
fieldPtr = itrPtr;
}

Position Application::Iterator::
operator
++
(
int
)

...
{
LPITRFIELDS itrPtr = (LPITRFIELDS)fieldPtr;
int nRow = itrPtr->nRow;
int nColumn = itrPtr->nColumn;

switch(itrPtr->nDirection++)

...{
case '0':
nRow--;
break;
case '1':
nColumn++;
break;
case '2':
nRow++;
break;
case '3':
nColumn--;
break;
default:
break;
}
Position next(nRow, nColumn);
return next;
}

bool
Application::Iterator::atEnd()

...
{
return ((LPITRFIELDS)fieldPtr)->nDirection >= 3;
}






































































































































二、下面就以迷宫为例子用这个“框架”

























































































































































































































