8数码,静态数组+自建开散列哈希表;
2010-06-13 19:31
155 查看
#include <stdio.h> #include <string.h> #include <stdlib.h> typedef int State[9]; const int MAXSTATE=1000000; //状态数不会超过这个,9!种 State st[MAXSTATE],goal; //状态数组, 目标状态 int dist[MAXSTATE]; // 已走步数 int fa[MAXSTATE]; // 前趋状态 /*移动方向*/ const int dx[]={-1,1,0,0}; const int dy[]={0,0,-1,1}; //自建hash const int MAXHASHSIZE=1000003; //比状态数多,是一个奇数,或者是质数 int head[MAXHASHSIZE],next[MAXHASHSIZE]; //初始化哈希表 void initHashTable() { memset(head,0,sizeof(head)); } //哈希函数,随便算,只要别超越int的范围,则可以以表长取余控制在数组范围内 int hash(State &s) { int v=0,i; for(i=0;i<9;++i) { v=v*10+s[i]; } return v%MAXHASHSIZE; } //判定插入 int tryToInsert(int s) { int h=hash(st[s]); int u=head[h]; while(u) //从桶内顺序查找是否存在这个状态 { if(memcmp(st[u],st[s],sizeof(st[s]))==0) //找到状态,说明重复了,就不必插入了 { return 0; } u=next[u]; } next[s]=head[h]; head[h]=s; return 1; } int bfs() { initHashTable(); //初始化状态哈希表为空 int front=1,rear=2; // 数组模拟队列,front队头,rear队尾 ,下标0不适用,作为无解判定,rear下标待存数据 while(front<rear) { State &s=st[front]; if(memcmp(goal,s,sizeof(s))==0) //到达目标状态,返回队头下标 return front; int z; for(z=0;z<9;++z) //找到空格位置 { if(!s[z]) { break; } } int x=z/3; int y=z%3; for(int d=0;d<4;++d) //以当前状态扩展新状态 { int newx=x+dx[d]; int newy=y+dy[d]; int newz=newx*3+newy; if(0<=newx&&newx<3&&0<=newy&&newy<3) //移动没有越界 { State &t=st[rear]; memcpy(t,s,sizeof(s)); //拷贝一份当前状态 t[newz]=s[z]; //移动 t[z]=s[newz]; dist[rear]=dist[front]+1; //修改距离 fa[rear]=front; // 修改前驱 if(tryToInsert(rear)) // 判断状态是否已出现过,出现过就不插入了,会重复运行 ++rear; } } ++front; //队头元素出队 } return 0; } int main() { int i,ans; for(i=0;i<9;++i) { scanf("%d",&st[1][i]); } for(i=0;i<9;++i) { scanf("%d",&goal[i]); } ans=bfs(); if(ans>0) { printf("%d/n",dist[ans]); } else { printf("-1/n"); } return 0; }
相关文章推荐
- 实现基于静态数组的顺序表的以下基本操作:
- 如何在C++11中正确的初始化静态常量成员数组
- 类的静态常量数组初始化
- 【C】【两维静态数组】2个例子
- C#超基础:静态数组与动态数组的区别
- c语言中静态数组的定义和初始化
- 静态数组的定义方法
- 利用哈希表 复杂数组去重
- 数组的静态初始化
- 基于静态数组的顺序表的一些基本操作(1)
- 静态数组实现堆栈
- hashset、hashmap、散列表数据结构(哈希表)它们之间的联系
- 全局对象/局部静态对象/new数组
- [置顶] Phone List(POJ-3630 and HDU-1671)(动态数组与静态数组)
- 静态数组实现的顺序表(C语言实现)
- 线性探测再散列解决冲突的哈希表
- 怎样在一个.c档里面取引用另一个.c档里面的静态结构体数组
- 数组、链表、哈希表
- 静态初始化数组由函数返回
- 动态数组与静态数组中第一个元素与数组名的关系