收藏 分销(赏)

九宫格实现算法.doc

上传人:s4****5z 文档编号:9007375 上传时间:2025-03-11 格式:DOC 页数:9 大小:65.50KB 下载积分:10 金币
下载 相关 举报
九宫格实现算法.doc_第1页
第1页 / 共9页
九宫格实现算法.doc_第2页
第2页 / 共9页


点击查看更多>>
资源描述
实验目的:通过visual c++进行算法编辑,准确掌握算法运行方式及流程。 通过程序实现类似九宫格的拼图效果,也叫做八方块。用最快的时间实现最后的效果:1 2 3 4 5 6 7 8 0 实验原理:先实现一个三行三列数组,再依次比较第一个数与上下左右数值的大小,进行移动,最后实现效果图。计算出一共移动的步数和每移一步的效果。 实验内容: 程序代码如下: // 8block.cpp : 定义控制台应用程序的入口点。 // #include "stdafx.h" #include <stdio.h> #include <stdlib.h> #include <time.h> #define GOAL 123804765//表示我们要找得目标状态 struct Node { short state[9];//存放结点的状态 short pos;//空格所在的位置,在数组中用0代表空格 struct Node *up;//空格上移后的状态 struct Node *down;//空格下移后的状态 struct Node *left;//空格左移后的状态 struct Node *right;//空格右移后的状态 struct Node *parent;//它是从哪一状态变换而来的 struct Node *next;//表示在队列中的下一个状态 } ; struct Tree { short key;//表示当前结点的数值 short * state;//表示当前状态的整个数组,当整颗树生成完毕后这一数组将被释放 short index;//表示当前数值在数组中的位置 bool visited;//对于叶子结点而言,表示这一结点是否被访问过 struct Tree * next;//指向它的(下一个)兄弟结点,表示这一位置的下一个数 struct Tree *down;//指向它的第一个孩子结点,表示下一位置的第一个数 }; struct Queue//定义一个队列用于广度优先遍历 { struct Node * front; struct Node * rear; }; void InitQueue(struct Queue *Q);//初始化一个空队列 bool QueueEmpty(struct Queue *Q);//判断队列是否为空 void EnQueue(struct Queue *Q,struct Node *N);//入队列 struct Node * DeQueue(struct Queue *Q);//出队列,返回队结点 void ClearQueue(struct Queue *Q);//清空队列 struct Node * GetBestPath(struct Node *tree);//找到一个最短路径,并返回最后的状态结点,如果没有路径返回NULL struct Tree * CreateCheckTree();//生成一个用于检查状态的查询树 void CreateSubCheckTree(struct Tree * T);//生成状态检查子树 void FreeCheckTree(struct Tree * checkTree);//释放状态检查树的空间 int checkCount=0;//检查结点状态次数 int deCount=0;//出队列次数 int enCount=0;//入队列次数 struct Tree * checkTree; void main() { struct Node* tree=new struct Node; tree->parent=NULL; printf("输入0-8的任意一个排列,其中0表示空格所在的位置:\n"); for(int i=0;i<=8;i++) { scanf("%d",&tree->state[i]); } for(int i=0;i<=8;i++) { if(tree->state [i]==0) { tree->pos =i; } } tree->next =NULL; int c1=clock(); struct Node *result=GetBestPath(tree); int c2=clock(); double t=(c2-c1)/1000.0; printf("状态检查次数:%d,入队列次数:=%d,出队列次数:%d\n",checkCount,enCount,deCount); if(result!=NULL) { int path[200]; int count=0; struct Node *N=result; while(N!=NULL) { path[count]=N->pos; N=N->parent; count++; } printf("有最短路径,共须%d步。\n下面给出各步空格出现的位置(第一个数为初始位置):\n",count-1); for(int i=count-1;i>=0;i--) { printf("%d ",path[i]); } } else { printf("不存在路径!"); } printf("\n所用时间为:%f秒",t); getchar(); getchar(); } void FreeCheckTree(struct Tree * checkTree) { if(checkTree->down!=NULL) { FreeCheckTree(checkTree->down); } if(checkTree->next!=NULL) { FreeCheckTree(checkTree->next); } delete checkTree; } struct Tree * CreateCheckTree() { struct Tree *T = new struct Tree; T->index =0; T->key =-1; T->next =NULL; T->down =NULL; T->state =new short[10]; T->state[0]=-1; for(int i=1;i<=9;i++) { T->state [i]=i-1; } CreateSubCheckTree(T); return T; } void CreateSubCheckTree(struct Tree * T) { if(T->index==8)//如果前八个数都排好了 { T->down =new struct Tree; T->down->key =T->state[9]; T->down->visited =false; T->down ->down =NULL; T->down ->next =NULL; delete T->state; } else { struct Tree *old=T; for(int i=T->index+1;i<10;i++) { struct Tree *current=new struct Tree; current->state =new short[10]; for(int j=0;j<=9;j++) { current->state [j]=T->state [j]; } current->index =T->index +1;//将指针前移 current->next =NULL; current->down =NULL; current->key=current->state[i];//将关键字设置为当前i所指处 int temp=current->state[current->index];//以下三句完成交换 current->state[current->index]=current->state[i]; current->state[i]=temp; if(i==T->index+1)//如果是第一个孩子 { T->down=current; old=current; } else { old->next =current; old=current; } CreateSubCheckTree(current); } delete T->state; } } bool checkNode(struct Node *N) { checkCount++; struct Tree *current=checkTree; for(int i=0;i<9;i++) { current=current->down; while(N->state[i]!=current->key) { current=current->next; } } if(current->visited==false) { current->visited =true; return true; } else { return false; } } struct Node * GetBestPath(struct Node *tree)//找到一个最短路径,并返回最后的状态结点,如果没有路径返回NULL { checkTree=CreateCheckTree(); // printf("分配完成!\n"); getchar(); int i; struct Queue *Q=new struct Queue; InitQueue(Q); EnQueue(Q,tree); while(!QueueEmpty(Q)) { struct Node *N=DeQueue(Q); int index=0; for(i=0;i<=8;i++) { index=index*10+N->state[i]; } if(index==GOAL) { FreeCheckTree(checkTree); ClearQueue(Q); return N; } if(N->pos>=3)//空格可以往上移 { struct Node *up=new struct Node; for(i=0;i<=8;i++) { up->state [i]=N->state [i]; } up->state[N->pos]=up->state [N->pos-3];//完成上移 up->state [N->pos-3]=0;//同上 up->pos =N->pos-3; if(checkNode(up))//如果这一状态以前没有出现过,保留这一状态 { N->up =up; up->parent =N; EnQueue(Q,up); } else//如果这一状态以前出现过, { delete up; N->up =NULL; } }//空格可以往上移 if(N->pos<=5)//空格可以往下移 { struct Node *down=new struct Node; for(i=0;i<=8;i++) { down->state [i]=N->state [i]; } down->state[N->pos]=down->state [N->pos+3];//完成下移 down->state [N->pos+3]=0;//同上 down->pos =N->pos+3; if(checkNode(down))//如果这一状态以前没有出现过,保留这一状态 { N->down =down; down->parent =N; EnQueue(Q,down); } else//如果这一状态以前出现过, { delete down; N->down =NULL; } }//空格可以往下移 if(N->pos!=0 && N->pos!=3 && N->pos!=6)//空格可以往左移 { struct Node *left=new struct Node; for(i=0;i<=8;i++) { left->state [i]=N->state [i]; } left->state[N->pos]=left->state [N->pos-1];//完成上移 left->state [N->pos-1]=0;//同上 left->pos =N->pos-1; if(checkNode(left))//如果这一状态以前没有出现过,保留这一状态 { N->left =left; left->parent =N; EnQueue(Q,left); } else//如果这一状态以前出现过, { delete left; N->left =NULL; } }//空格可以往左移 if(N->pos!=2 && N->pos!=5 && N->pos!=8)//空格可以往右移 { struct Node *right=new struct Node; for(i=0;i<=8;i++) { right->state [i]=N->state [i]; } right->state[N->pos]=right->state [N->pos+1];//完成上移 right->state [N->pos+1]=0;//同上 right->pos =N->pos+1; if(checkNode(right))//如果这一状态以前没有出现过,保留这一状态 { N->right =right; right->parent =N; EnQueue(Q,right); } else//如果这一状态以前出现过, { delete right; N->right =NULL; } }//空格可以往右移 } FreeCheckTree(checkTree); return NULL; } void InitQueue(struct Queue *Q)//初始化一个空队列 { struct Node * head=new struct Node; head->next =NULL; Q->front =head; Q->rear=head; }; bool QueueEmpty(struct Queue *Q)//判断队列是否为空 { if(Q->front ==Q->rear ) { return true; } else { return false; } }; void EnQueue(struct Queue *Q,struct Node *N)//入队列 { enCount++; Q->rear->next=N; Q->rear=N; }; struct Node * DeQueue(struct Queue *Q)//出队列,返回队结点 { deCount++; if(Q->front ==Q->rear ) { printf("队列已空!!\n"); return NULL; } else { struct Node *N=Q->front->next; Q->front->next=N->next; if(Q->rear==N) { Q->rear =Q->front; } return N; } } void ClearQueue(struct Queue *Q)//清空队列 { while(!QueueEmpty(Q)) { delete(DeQueue(Q)); } } 实验结果:
展开阅读全文

开通  VIP会员、SVIP会员  优惠大
下载10份以上建议开通VIP会员
下载20份以上建议开通SVIP会员


开通VIP      成为共赢上传

当前位置:首页 > 包罗万象 > 大杂烩

移动网页_全站_页脚广告1

关于我们      便捷服务       自信AI       AI导航        抽奖活动

©2010-2025 宁波自信网络信息技术有限公司  版权所有

客服电话:4009-655-100  投诉/维权电话:18658249818

gongan.png浙公网安备33021202000488号   

icp.png浙ICP备2021020529号-1  |  浙B2-20240490  

关注我们 :微信公众号    抖音    微博    LOFTER 

客服