参考:http://www.cnblogs.com/hustcat/archive/2008/04/09/1144645.html
方法:(回溯法)
1、总结问题解决问题的思想。
2、总结具体的算法流程和典型问题解决思路。
3、编程实现具体实例。
将这个方法推广到其他算法上,快速高效的掌握算法思想。
回溯法一种系统的搜索问题解答的办法。
1、思想:碰壁返回
2、算法流程:首先定义一个解空间,这个解空间必须至少包含问题的一个解。其次需要组织解空间使它容易被搜索,典型的组织方法是图或者二叉搜索树。最后按深度优先搜索的方法从开始结点开始搜索。
在搜索的任意时刻,只保存开始结点到当前结点的路径。
3、具体实例(迷宫问题)
// Maze.cpp : 定义控制台应用程序的入口点。 // #include "stdafx.h" #include<stack> #include<iostream> using namespace std; #define MazeNum 10 //通道块坐标结点 struct PosType { int x; //横坐标 int y; //纵坐标 }; //入栈结点类型 struct SElemType { int ord; //通道块在路径上的序号 PosType seat; //通道块在迷宫中的坐标位置 int di; //从此通道块走向下一个通道的方向 }; //路径全局变量 PosType path[64]; int _tmain(int argc, _TCHAR* argv[]) { cout<<"----------------回溯法求解迷宫问题----------"<<endl; int maze[MazeNum][MazeNum]= //迷宫方阵 入口:(1,1) 出口:(8,8) { {1,1,1,1,1,1,1,1,1,1},//0 {1,0,0,1,0,0,0,1,0,1},//1 {1,0,0,1,0,0,0,1,0,1},//2 {1,0,0,0,0,1,1,0,0,1},//3 {1,0,1,1,1,0,0,0,0,1},//4 {1,0,0,0,1,0,0,0,0,1},//5 {1,0,1,0,0,0,1,0,0,1},//6 {1,0,1,1,1,0,1,1,0,1},//7 {1,1,0,0,0,0,0,0,0,1},//8 {1,1,1,1,1,1,1,1,1,1} //9 }; //初始化路径数组 for(int i=0;i<64;i++) { path[i].x=0; path[i].y=0; } PosType start,end; start.x=1; start.y=1; end.x=8; end.y=8; PosType NextPosition(PosType curpos,int di); bool Maze(int maze[MazeNum][MazeNum],PosType start,PosType end); void PrintPath(); //如果该迷宫可以通行,则打印路径 if(Maze(maze,start,end)) { PrintPath(); } else { cout<<"从起点到终点木有路径可达"<<endl; } return 0; }//main //选择当前位置的下一个位置:1:东 2:南 3:西 4:北 PosType NextPosition(PosType curpos,int di) { PosType nextpos; switch (di) { case 1: //东 nextpos.x=curpos.x+1; nextpos.y=curpos.y; return nextpos; break; case 2: //南 nextpos.x=curpos.x; nextpos.y=curpos.y+1; return nextpos; break; case 3: //西 nextpos.x=curpos.x-1; nextpos.y=curpos.y; return nextpos; break; case 4: //北 nextpos.x=curpos.x; nextpos.y=curpos.y-1; return nextpos; default: break; } }//NextPosition //迷宫算法 bool Maze(int maze[MazeNum][MazeNum],PosType start,PosType end) { PosType cur_postion=start; //设定当前位置为入口位置 int curstep=0; //探索第一步 stack<SElemType> m_stack; //初始化栈 SElemType setType; do { //如果当前位置可以通过 if (maze[cur_postion.x][cur_postion.y]==0) { setType.ord=curstep; setType.seat=cur_postion; setType.di=1; //记录该路径 path[curstep]=cur_postion; m_stack.push(setType); //入栈 //如果当前位置等于终点,则结束,否则切换到当前位置的东邻方向 if(cur_postion.x==end.x && cur_postion.y==end.y)return true; cur_postion=NextPosition(cur_postion,1); //切换到下一个位置 curstep++; //当前路径长度加1 } //如果当前位置不能通过,则回溯 else { //当前栈不为空,且有其他方向没有探索 if(!m_stack.empty()) { setType=m_stack.top(); //访问栈顶元素 cur_postion=setType.seat; //返回上一个位置 m_stack.pop(); //删除栈顶元素 while(setType.di==4 && !m_stack.empty()) { // m_stack.pop(); //如果某个路径的其他路径都不通,只能后退一步 }//while if(setType.di<4) //还有其他方向未被探索 { setType.di++; //切换到下一个方向 cur_postion =NextPosition(cur_postion,setType.di); } } } } while (!m_stack.empty()); return false; }//Maze //打印路径 void PrintPath() { int i=0; while(path[i].x!=0 && path[i].y!=0) { cout<<"("<<path[i].x<<","<<path[i].y<<")"<<"-->"; i++; if(i%4==0) cout<<endl; } cout<<endl; }//PrintPath
声明:此程序中存在一点小bug,待修复。