程序代码:
#include <stdio.h>
#include <string.h>
typedef int State[9];//状态类型 存储八数码
State queue[100000];//队列
int step[100000];//对应结点到根结点的距离,即步骤
const int dx[] = {0,0,1,-1};//定义方向
const int dy[] = {-1,1,0,0};
int front,rear;
const int MAXHASHSIZE = 1000003;
int head[MAXHASHSIZE],next[MAXHASHSIZE];
int vis[36288],fact[9];
int bfs(State &r,State & g);
int main(){
State root,goal;
while(1){
for(int i = 0; i < 9; i++)
scanf("%d",&root[i]);
for(int i = 0; i < 9; i++)
scanf("%d",&goal[i]);
int ans = bfs(root,goal);
if(ans > 0)
printf("%d ",step[ans]);
else
printf("-1\n");
}
}
int bfs(State & r,State &g){
init_lookup_table();
memset(step,0,sizeof(step));//初始化所有状态对应步骤
front = rear = 0;
memcpy(queue[rear++],r,sizeof(r));//跟结点入队列
while(front < rear){
State v;
memcpy(v,queue[front++],sizeof(v));//出队列
if(memcmp(v,g,sizeof(g)) == 0)
return front - 1;
int z;
for(z = 0 ; z < 9 ; z++)
if(!v[z])
break;
int xx = z / 3; //行号
int yy = z % 3; //列号
for(int d = 0 ; d < 4 ; d++){//扫描四个方向
int newx = xx + dx[d];//新方向
int newy = yy + dy[d];
if(newx >=0 && newx <= 2 && newy >=0 && newy <= 2){//如果该方向合法,则入队列
int k = 3 * newx + newy; //记录下这个方向的编号
State u;
memcpy(u,v,sizeof(v));
u[z] = u[k];// 实现移动
u[k] = 0;
memcpy(queue[rear],u,sizeof(u));//入队列
step[rear - 1] = step[front - 1] + 1;//更新对应结点的所对应步骤
if(try_to_insert(rear))
rear++;
}
}
}
}
这段代码不是完全自己写的,而且还有个要借助hash函数的功能没完成,写的时候有参考LRJ的算法书籍。改天学习下hash算法再补充完整,先结贴了。