启发式搜索算法解决八数码问题(C语言).doc
《启发式搜索算法解决八数码问题(C语言).doc》由会员分享,可在线阅读,更多相关《启发式搜索算法解决八数码问题(C语言).doc(9页珍藏版)》请在冰豆网上搜索。
![启发式搜索算法解决八数码问题(C语言).doc](https://file1.bdocx.com/fileroot1/2022-10/4/5a28783f-6382-4a15-b195-414da0746229/5a28783f-6382-4a15-b195-414da07462291.gif)
1、程序源代码
#include
#include
structnode{
inta[3][3];//用二维数组存放8数码
inthx;//函数h(x)的值,表示与目标状态的差距
structnode*parent;//指向父结点的指针
structnode*next;//指向链表中下一个结点的指针
};
//------------------hx函数-------------------//
inthx(ints[3][3])
{//函数说明:
计算s与目标状态的差距值
inti,j;
inthx=0;
intsg[3][3]={1,2,3,8,0,4,7,6,5};
for(i=0;i<3;i++)
for(j=0;j<3;j++)
if(s[i][j]!
=sg[i][j])
hx++;
returnhx;
}
//-------------hx函数end----------------------//
//-------------extend扩展函数----------------//
structnode*extend(node*ex)
{//函数说明:
扩展ex指向的结点,并将扩展所得结点组成一条
//单链表,head指向该链表首结点,并且作为返回值
inti,j,m,n;//循环变量
intt;//临时替换变量
intflag=0;
intx[3][3];//临时存放二维数组
structnode*p,*q,*head;
head=(node*)malloc(sizeof(node));//head
p=head;
q=head;
head->next=NULL;//初始化
for(i=0;i<3;i++)//找到二维数组中0的位置
{
for(j=0;j<3;j++)
if(ex->a[i][j]==0)
{
flag=1;
break;
}
if(flag==1)
break;
}
for(m=0;m<3;m++)//将ex->a赋给x
for(n=0;n<3;n++)
x[m][n]=ex->a[m][n];
//根据0的位置的不同,对x进行相应的变换
//情况1
if(i-1>=0)
{
t=x[i][j];x[i][j]=x[i-1][j];x[i-1][j]=t;
flag=0;
for(m=0;m<3;m++)//将x赋给a
for(n=0;n<3;n++)
if(x[m][n]==ex->parent->a[m][n])
flag++;
if(flag!
=9)
{
q=(node*)malloc(sizeof(node));
for(m=0;m<3;m++)//将x赋给a
for(n=0;n<3;n++)
q->a[m][n]=x[m][n];
q->parent=ex;
q->hx=hx(q->a);
q->next=NULL;
p->next=q;
p=p->next;
}
}
//情况2
for(m=0;m<3;m++)//将ex->a重新赋给x,即还原x
for(n=0;n<3;n++)
x[m][n]=ex->a[m][n];
if(i+1<=2)
{
t=x[i][j];x[i][j]=x[i+1][j];x[i+1][j]=t;
flag=0;
for(m=0;m<3;m++)
for(n=0;n<3;n++)
if(x[m][n]==ex->parent->a[m][n])
flag++;
if(flag!
=9)
{
q=(node*)malloc(sizeof(node));
for(m=0;m<3;m++)//将x赋给a
for(n=0;n<3;n++)
q->a[m][n]=x[m][n];
q->parent=ex;
q->hx=hx(q->a);
q->next=NULL;
p->next=q;
p=p->next;
}
}
//情况3
for(m=0;m<3;m++)//将ex->a重新赋给x,即还原x
for(n=0;n<3;n++)
x[m][n]=ex->a[m][n];
if(j-1>=0)
{
t=x[i][j];x[i][j]=x[i][j-1];x[i][j-1]=t;
flag=0;
for(m=0;m<3;m++)
for(n=0;n<3;n++)
if(x[m][n]==ex->parent->a[m][n])
flag++;
if(flag!
=9)
{
q=(node*)malloc(sizeof(node));
for(m=0;m<3;m++)//将x赋给a
for(n=0;n<3;n++)
q->a[m][n]=x[m][n];
q->parent=ex;
q->hx=hx(q->a);
q->next=NULL;
p->next=q;
p=p->next;
}
}
//情况4
for(m=0;m<3;m++)//将ex->a重新赋给x,即还原x
for(n=0;n<3;n++)
x[m][n]=ex->a[m][n];
if(j+1<=2)
{
t=x[i][j];x[i][j]=x[i][j+1];x[i][j+1]=t;
flag=0;
for(m=0;m<3;m++)
for(n=0;n<3;n++)
if(x[m][n]==ex->parent->a[m][n])
flag++;
if(flag!
=9)
{
q=(node*)malloc(sizeof(node));
for(m=0;m<3;m++)
for(n=0;n<3;n++)
q->a[m][n]=x[m][n];
q->parent=ex;
q->hx=hx(q->a);
q->next=NULL;
p->next=q;
p=p->next;
}
}
head=head->next;
returnhead;
}
//---------------extend函数end-----------------------//
//----------------insert函数-------------------------//
node*insert(node*open,node*head)
{//函数说明:
将head链表的结点依次插入到open链表相应的位置,
//使open表中的结点按从小到大排序。
函数返回open指针
node*p,*q;//p、q均指向open表中的结点,p指向q所指的前一个结点
inti,j;
intflag=0;
if(open==NULL)//初始状态,open表为空
{//首先将head表第一个结点直接放入open表中
open=head;
q=head;
head=head->next;
q->next=NULL;
//再插入第二个结点
if(head->hxhx)
{//插入到首结点位置
open=head;
head=head->next;
open->next=q;
}
else
{//或者第二个结点的位置
q->next=head;
head=head->next;
q=q->next;
q->next=NULL;
p=open;
}
p=open;
q=open->next;
}//endif
while(head!
=NULL)
{
q=open;
if(head->hxhx)//插入到表头
{
open=head;
head=head->next;
open->next=q;
continue;
}
else{q=q->next;p=open;}//否则,q指像第二个结点,p指向q前一个结点
while(q->next!
=NULL)//将head的一个结点插入到链表中(非表尾的位置)
{
if(q->hxhx)
{
q=q->next;
p=p->next;
}
else
{
p->next=head;
head=head->next;
p->next->next=q;
break;
}
}
if(q->next==NULL)//将head的一个结点插入到表尾
{
if(q->hx>head->hx)
{
p->next=head;
head=head->next;
p->next->next=q;
}
else
{
q->next=head;
head=head->next;
q->next->next=NULL;
}
}//if
}//while
returnopen;
}//insert
//-----------------insert函数end--------------------//
//---