一、回溯算法简单说就是“一直向前走,碰壁就会头”。一个经典的例子是走迷宫,一直向前走,碰壁就回头。下面就看看这个“框架”(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;
}






































































































































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

























































































































































































































