您的位置:首页 > 理论基础 > 数据结构算法

[数据结构]八数码(暴力,解答树,BFS+hash)

2015-06-22 10:42 585 查看
/*
Name:八数码(BFS+hash)

Actor:HT

Time:2015年6月22日

Error Reporte:

1.memcmp==0 代表匹配成功

2.memcpy(&+数组名,&+数组名,sizeof(数组名))

}
*/

#include"stdio.h"
#include"iostream"
#include"string.h"

using namespace std;

int map[1000000][9];		//看做无限大队列,其中每个元素都具有9个点,也就是说每个元素都是一张图
int goal[9];
int ans[1000000];		//答案,移动的步数,也就是深度,要对应每个元素

const int my[4] = { -1, 0, 1, 0 };
const int mx[4] = { 0, 1, 0, -1 };				//图上移动,这样很方便  分别为上右下左
const int mz[4] = { -3, 1, 3, -1 };				//串上移动

int hashhead[1000000] = { 0 };			//无数个空hash的表头,每个表头用于存储hash值一样的一类“map元素的序号”,下标是个hash值
int hashtable[1000000] = { 0 };			//无数个指向空的hash的指针,每个指针的下标和值都是“map元素的序号”;其实就是一个“序号”组成的链表

int fa[10000000] = { 0 };		//写着玩
void print(int m)				//写着玩
{
int i;
for (i = 0; i < 9; i++)
{
cout <<map[m][i]<< " ";
if (i % 3 == 2) cout << endl;
}
}

int ahash(int rear)
{
int i,t=0;
for (i = 0; i < 9; i++)				//hash数值设定,把所有的情况归结到几个hash值中
{
t *= 10;
t += map[rear][i];
t %= 1000000;
}
int rearlyhash = hashhead[t];		//找到这个hash数值应该对应的表的表头的真值(某个map元素的元素序号)
while (rearlyhash)			//沿着这条链表开始搜索
{
if (memcmp(map[rearlyhash], map[rear], sizeof(map[rear])) == 0)	return 0;
rearlyhash = hashtable[rearlyhash];
}
hashtable[rear] = hashhead[t];		//这个新来的序号(rear)的下一个指向表头
hashhead[t] = rear;					//新来的序号成为了新的表头
return 1;
}

int bfs()
{
int zero,x,y;		//零点在串的位置,以及在图的坐标
int i;
int front = 1, rear = 2;
ans[front] = 0;
while (front < rear)
{
if (memcmp(map[front],goal,sizeof(goal)) == 0)  return front;
for (i = 0; i < 9; i++)
if (map[front][i] == 0)
{
zero = i;
break;
}											//先找到0点
x = zero % 3;								//分别为0   1   2
y = zero / 3;								//分别为0   1   2
for (i = 0; i < 4; i++)
{
int newx = x + mx[i], newy = y + my[i], newz= zero + mz[i];
if (newx > 2 || newx < 0 || newy > 2 || newy < 0)	continue;
memcpy(&map[rear], &map[front], sizeof(map[front]));
map[rear][zero] = map[front][newz];
map[rear][newz] = map[front][zero];	//生成新的map,准备放入队列
ans[rear] = ans[front] + 1;
fa[rear] = front;					//写着玩,印图用
if (ahash(rear)==1) rear++;
}
front++;
}
}

int main()
{
int i,sum;
for (i = 0; i < 9; i++)
cin >> map[1][i];
for (i = 0; i < 9; i++)
cin >> goal[i];
sum = bfs();
cout << ans[sum]<<endl;
for (i = sum; fa[i] != 0; i = fa[i])		//写着玩
{
print(i);
cout << "\n\n";
}
system("pause");
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: