数据结构实验三
南昌航空大学实验报告
二0 21 年 5月 10 日
课程名称: 数据结构实验 实验名称: 栈与队列的综合运用
班级: 姓名: 同组人:
指导教师评定: 签名:
1.必做:
1.题目:设计并验证一下算法:首先将一个中缀表达式转化为逆波兰式,然后对此逆波兰表达式求值。
1)表达式求值是程序设计语言编译中的一个最基本的问题。通常,表达式由运算符、操作数、界限符组成,算术表达式中最常见的表示法形式有中缀、前缀和后缀表示法。中缀表示法是书写表达式的常见方式,前缀和后缀表示法主要用于计算机科学领域。
①中缀表达式:运算符在两操作数的中间。在运算中存在运算符的优先权与结合性的问题。例如运算a/b-(c+d)*f时,编译器即自左向右逐一检查,当检查到第一个运算符“/”时还无法知道是否执行;待检查到第二个运算符“-”时,因为知道“/”的优先级别高于“-”时,才知道执行“a/b";当继续检查到“(”时,可知道先执行括号以内部分。
②前缀表达式:运算符放在两操作数的前面。这种表示法经常用于计算机科学,特别是编译器设计方面。为纪念其发明家Jan Lukasiewicz,该表示法也称波兰表示法。
③后缀表达式:运算符放在两操作数的后面。后缀表达式也称逆波兰表达式,因其使表达式求值变得轻松,所以被普遍使用。
前缀和后缀表示法有以下共同特征:操作数的顺序与等价的中缀表达式中操作数的顺序一致、不需要括号、操作符的优先级不相关。
(2)要求从键盘读入一个包括加减乘除、括号与正整数的中缀表达式,将其转换成后缀表达式存入一张线性表并输出,对后缀表达式求值并输出。
(3)将中缀表达式转换成后缀表达式的过程中,需要定义一个运算符栈;对后缀表达式求值的过程中,需要定义一个操作数栈。
(4)教材“表3.1 算符间的优先关系”可用一个二维字符数组来描述:
char Prior[7][7]={‘>’,‘>’,‘<’,‘<’,‘<’,‘>’,‘>’,
‘>’,‘>’,‘<’,‘<’,‘<’,‘>’,‘>’,
‘>’,‘>’,‘>’,‘>’,‘<’,‘>’,‘>’,
‘>’,‘>’,‘>’,‘>’,‘<’,‘>’,‘>’,
‘<’,‘<’,‘<’,‘<’,‘<’,‘=’,‘ ’,
‘>’,‘>’,‘>’,‘>’,‘ ’,‘>’,‘>’,
‘<’,‘<’,‘<’,‘<’,‘<’,‘ ’,‘=’}
————————————————
一、 需求分析
1、在本次实验中,首先,从键盘输入中缀表达式的信息,然后将中缀表达式转换为逆波兰式,接着输出逆波兰式,再对中缀表达式进行求值,最后输出所求值。
2. 演示程序以用户和计算机对话的方式进行,即在计算机终端上显示“提示信息”之后,由用户在键盘上先后输入中缀表示式。输出逆波兰式以及它的值。
3. 程序执行的命令包括:
(1) 输入中缀表达式;
(2) 将中缀表达式转换为逆波兰式并输出;
(3) 对中缀表达式进行求值并输出;
(4) 结束。
4. 测试数据
输入:
请输入中缀表达式:
12+(2*3+4)/10
逆波兰式表达式为:
-12 2 3* 4 +10 \ +
12+(2*3+4)/10=-11.00
二、 概要设计
1. 抽象数据类型定义
为实现上述程序功能,需要一个抽象数据类型:图。
ADT Graph{
基本操作:
is_lawful(char a)
操作结果:判断输入的a是否满足要求
InitStack(Stack &Stack)
操作结果:将存放字符栈初始化
InitStack1(Stack1 &Stack)
操作结果:将存放数字栈初始化
InitNipolan(Nibolan &ni)
操作结果:将存放逆波兰式栈初始化
Push(Stack &Stack,char a)
操作结果:运算符入栈
Push1(Stack1 &Stack,double a)
操作结果:数字入栈
is_number(char a)
操作结果:判断输入是字符还是数字
compare(char a1,char a2)
操作结果:运算符比较
Zhuanhuan(char a)
操作结果:将ASCII码转换为数字
Pop(Stack &s)
操作结果:出栈
Pop1(Stack1 &s)
操作结果:出栈
Get_top(Stack &s)
操作结果:取栈顶元素
Get_top1(Stack1 &s)
操作结果:取栈顶元素
count(double x1,double x2,char c)
操作结果:输出两数做运算得到的值
Input_(char *a)
操作结果:输入
Handle(int num,char *a,Stack &s,Stack1 &s1,Nibolan &ni)
操作结果:进行逆波兰式转换计算与输出
Output(int num,char *a,Stack1 s1)
操作结果:输出
2.程序模块
(1)主程序流程
void main{
初始化操作数栈s;
初始化运算符栈s1;
初始化逆波兰表达式存储栈ni;
输入中缀表达式;
对中缀表达式进行操作,将它转换为后缀表达式,并求值。
输出后缀表达式;
输出并输出结果。
}
(2) 构建操作数栈模块;
(3) 构建运算符栈模块;
(4) 判断字符是否合法模块。
(5) 字符转换为数字模块;
(6) 字符存入运算符栈模块;
(7) 数字存入操作数栈模块
(8) 两数进行运算模块
(9) 判断是否为数字模块
(10) 符号优先级比较模块
(11) 出栈模块
(12) 取栈顶元素模块
(13) 输入中缀表达式模块
(14) 输出模块
3.程序结构图
各模块之间的调用关系如图所示。
图1 模块之间调用关系图
三、 详细设计
1.数据类型及结构体
ypedef struct{//运算符栈,char型
ElemType1 *base;//栈底指针
ElemType1 *top;//栈顶指针
int Stacksize;
}Stack;
typedef struct{//数字栈,double型
ElemType2 *base;//栈底指针
ElemType2 *top;//栈顶指针
int Stacksize;
}Stack1;
typedef struct{
ElemType1 *a[50];
ElemType num;
}Nibolan;
bool is_lawful(char a)
int InitStack(Stack &Stack)
int InitStack1(Stack1 &Stack)
int InitNipolan(Nibolan &ni)
int Push(Stack &Stack,char a)
int Push1(Stack1 &Stack,double a)
bool is_number(char a)
bool compare(char a1,char a2)
int Zhuanhuan(char a)
char Pop(Stack &s)
double Pop1(Stack1 &s)
char Get_top(Stack &s)
double Get_top1(Stack1 &s)
double count(double x1,double x2,char c)
int Input_(char *a)
int Handle(int num,char *a,Stack &s,Stack1 &s1,Nibolan &ni)
int Output(int num,char *a,Stack1 s1)
2.主函数
int main(){
Stack s;//运算符栈
Stack1 s1;//数字栈
InitStack(s);
InitStack1(s1);
char a[50];
Nibolan ni;
InitNipolan(ni);
int num = Input_(a);
Handle(num,a,s,s1,ni);
Output(num,a,s1);
return 0;
}
四、 调试分析
1. 第一次完成时无法实现多位数的运算加了段代码while(is_number(a[i+1]))
{count = count*10;
count=count+Zhuanhuan(a[i+1]);
i++;}
便可以进行多位数的运算
2.再次检查发现无法对负数进行识别,便引入一个参数y来控制为正为负if(a[i]=='-'&&(a[i-1]=='+'||a[i-1]=='-'||a[i-1]=='*'||a[i-1]=='/'||a[i-1]=='('||a[i-1]=='#')){
y=-1;}
3.测试时发现第一个输入的是负数时转换成逆波兰式时会出错,添加代码
if(i==0&&a[i]=='-'){y=-1;}else
4.该代码的时间复杂度为O(n)
五、 用户手册
1. 本程序的运行环境为DOS操作系统,执行文件为:main.exe。
2. 进入演示程序后即显示文本方式的用户界面。
3. 程序运行后,按照提示信息输入中缀表达式的信息。
4. 输出结果分别后缀表达式以及中缀表达式的值。
六、测试结果
测试结果
输入:
请输入中缀表达式:
12+(2*3+4)/10
逆波兰式表达式为:
-12 2 3* 4 +10 \ +
12+(2*3+4)/10=-11.00
七、附录
源代码:#include<stdio.h>
#include<stdlib.h>
#define STACK_SIZE 50
typedef int ElemType;
typedef char ElemType1;
typedef double ElemType2;
typedef struct{//运算符栈,char型
ElemType1 *base;//栈底指针
ElemType1 *top;//栈顶指针
int Stacksize;
}Stack;
typedef struct{//数字栈,double型
ElemType2 *base;//栈底指针
ElemType2 *top;//栈顶指针
int Stacksize;
}Stack1;
typedef struct{
ElemType1 *a[50];
ElemType num;
}Nibolan;
bool is_lawful(char a){//判断输入合法性
if(a!='+' && a!='-' && a!='*' && a!='/' && a!=')' && a!='('){
if(a<48 || a>57){
return false;
}
}
return true;
}
int InitStack(Stack &Stack){//初始化栈
Stack.base = (char*)malloc(STACK_SIZE*sizeof(char));
Stack.top = Stack.base;
Stack.Stacksize = STACK_SIZE;
return 0;
}
int InitStack1(Stack1 &Stack){//初始化栈
Stack.base = (double*)malloc(STACK_SIZE*sizeof(double));
Stack.top = Stack.base;
Stack.Stacksize = STACK_SIZE;
return 0;
}
int InitNipolan(Nibolan &ni){//初始化栈
ni.num = 50;
for(int i=0;i<ni.num;i++){
ni.a[i] = (char*)malloc(2*sizeof(char));
}
return 0;
}
int Push(Stack &Stack,char a){//入运算符栈
if(Stack.top-Stack.base >= Stack.Stacksize){
Stack.base = (char*)realloc(Stack.base,
(Stack.Stacksize+STACK_SIZE) * sizeof (char) );
Stack.top = Stack.base + Stack.Stacksize;
Stack.Stacksize += STACK_SIZE;
}
*(Stack.top) = a;
Stack.top++;
return 0;
}
int Push1(Stack1 &Stack,double a){//入数字栈
if(Stack.top-Stack.base >= Stack.Stacksize){
Stack.base = (double*)realloc(Stack.base,
(Stack.Stacksize+STACK_SIZE) * sizeof (double) );
Stack.top = Stack.base + Stack.Stacksize;
Stack.Stacksize += STACK_SIZE;
}
*(Stack.top) = a;
Stack.top++;
return 0;
}
bool is_number(char a){//判断输入是否为数字
if(a<48 || a>57){
return false;
}
return true;
}
bool compare(char a1,char a2){//比较运算符大小,a1为要入栈元素,a2为栈顶元素,a1>a2时能入栈
if(a2=='#' || a2=='('){
return true;
}
else if(a1=='('){
return true;
}
else if( (a1=='*' ||a1=='/') && (a2=='+' || a2=='-') )
{
return true;
}
else{
return false;
}
}
int Zhuanhuan(char a){//转换成数字
int x;
x = (int)a-48;
return x;
}
char Pop(Stack &s){//出栈
return *--s.top;
}
double Pop1(Stack1 &s){//出栈
return *--s.top;
}
char Get_top(Stack &s){//获取运算符栈栈顶元素
char S = *(s.top-1);
return S;
}
double Get_top1(Stack1 &s){//获取数字栈栈顶元素
double S = *(s.top-1);
return S;
}
double count(double x1,double x2,char c){//计算 ,x1-x2,x1/x2
double x;
switch(c){
case '-': x = x1-x2; break;
case '+': x = x1+x2; break;
case '*': x = x1*x2; break;
default :x = x1/x2;
}
return x;
}
int Input_(char *a){//输入函数
char a1;
int num1=0;
printf("请输入中缀表达式:\n");
a1 = getchar();
while(a1!='\n'){
if(!is_lawful(a1)){
printf("ERROR");
exit(0);
break;
}
a[num1] = a1;
a1 = getchar();
num1++;
}
return num1;
}
int Handle(int num,char *a,Stack &s,Stack1 &s1,Nibolan &ni){
int i,n = 0;
int y=1;
double x;
Push(s,'#');
printf("逆波兰式表达式为:\n");
for(i=0;i<num;i++){
if(i==0&&a[i]=='-')
{
y=-1;
}else
if(is_number(a[i])){//是数字,入栈
int count = Zhuanhuan(a[i]);
while(is_number(a[i+1]))
{
count = count*10;
count=count+Zhuanhuan(a[i+1]);
i++;
}
x = count*y;
y=1;
itoa(x,ni.a[n],10);
printf("%s ",ni.a[n]);
n++;
Push1(s1,x);
}
else if(a[i]=='-'&&(a[i-1]=='+'||a[i-1]=='-'||a[i-1]=='*'||a[i-1]=='/'||a[i-1]=='('||a[i-1]=='#')){
y=-1;
}
else{//判断运算符情况
if(a[i]==')'){
while(Get_top(s)!='('){
char c = Pop(s);
char Q[2];
Q[0] = c;
Q[1] = '\0';
ni.a[n] = Q;
printf("%s ",ni.a[n]);
n++;
double x1 = Pop1(s1);
double x2 = Pop1(s1);
double P = count(x2,x1,c);
Push1(s1,P);
}
char Q = Pop(s);//把(取出
}
else{
while(!compare(a[i],Get_top(s))){
char c = Pop(s);
char Q[2];
Q[0] = c;
Q[1] = '\0';
ni.a[n] = Q;
printf("%s ",ni.a[n]);
n++;
double x1 = Pop1(s1);
double x2 = Pop1(s1);
double P = count(x2,x1,c);
Push1(s1,P);
}
Push(s,a[i]);
}
}
}
while(s.top-s.base!=1){
char c = Pop(s);
char Q[2];
Q[0] = c;
Q[1] = '\0';
ni.a[n] = Q;
printf("%s ",ni.a[n]);
n++;
double x1 = Pop1(s1);
double x2 = Pop1(s1);
double P = count(x2,x1,c);
Push1(s1,P);
}
printf("\n");
return 0;
}
int Output(int num,char *a,Stack1 s1){//输出结果
int i=0;
printf("\n");
for(i=0;i<num;i++){
printf("%c",a[i]);
}
printf(" = %.2f",Get_top1(s1));
}
int main(){
Stack s;//运算符栈
Stack1 s1;//数字栈
InitStack(s);
InitStack1(s1);
char a[50];
Nibolan ni;
InitNipolan(ni);
int num = Input_(a);
Handle(num,a,s,s1,ni);
Output(num,a,s1);
return 0;
}
2.必做:
用栈与递归实现杨辉三角
一、 需求分析
1.本次实验只需输入想输出杨辉三角的层数即可;
2.程序执行命令:
输入杨辉三角层数
杨辉三角生成
输出杨辉三角
3.测试数据
请输入行数:
5
1
1 1
1 2 1
1 3 3 1
1 4 6 4 1
二、 概要设计
1. 抽象数据类型定义
为实现上述程序功能,需要一个抽象数据类型:
ADT Graph{
基本操作:
InitQueue(CyQueue &Q)
操作结果:将队列初始化
InQueue(CyQueue &Q,int a)
操作结果:将a入队列
OutQueue(CyQueue &Q,int a)
操作结果:将a出队列
yanghui(CyQueue &Q)
操作结果:杨辉三角的生成
}
2.程序模块
主函数:int main()
{
输入杨辉三角行数
创建队列
队列初始化
生成杨辉三角并输出
}
3.模块之间的调用
三、 详细设计
1.数据结构体类型:typedef int ElemType;
typedef struct{
ElemType data[MAXSIZE];//队列的存储空间
int front;//队列的队头指针
}CyQueue;
void InitQueue(CyQueue &Q)
void InQueue(CyQueue &Q,int a)
int OutQueue(CyQueue &Q,int a)
void yanghui(CyQueue &Q)
2.主函数:int main()
{
printf("请输入行数:\n");
CyQueue Q;
InitQueue(Q);
yanghui(Q);
}
四、 调试分析
1.第一次生成的杨辉三角只有前三层能顺利输出,后面存在错误,经分析是因为有些数用到了两次,因此改正为:for(i=0;i<a;i++)
{
for(j=0;j<i+1;j++)
{
if(j==0)
{
b=1;
printf("%d ",b);
InQueue(Q,b);
}
else if(j==i)
{
b=1;
printf("%d ",b);
InQueue(Q,b);
}
else{
b=OutQueue(Q,d+j)+OutQueue(Q,d+j-1);
printf("%d ",b);
InQueue(Q,b);
}
}
2.时间复杂度为O(n),而递归实现的时间复杂度则为O(n*n)
五、 用户手册
1. 本程序的运行环境为DOS操作系统,执行文件为:main.exe。
2. 进入演示程序后即显示文本方式的用户界面。
3. 程序运行后,按照提示信息输入杨辉三角行数的信息。
4. 输出生成的杨辉三角。
六、 测试结果
请输入行数:
5
1
1 1
1 2 1
1 3 3 1
1 4 6 4 1
七、 附录
源代码:
#include <stdio.h>
#include <stdlib.h>
#define MAXSIZE 100000 //队列的最大长度
typedef int ElemType;
typedef struct{
ElemType data[MAXSIZE];//队列的存储空间
int front;//队列的队头指针
}CyQueue;
void InitQueue(CyQueue &Q){//初始化
Q.front=0;
}
void InQueue(CyQueue &Q,int a){
Q.data[Q.front++]=a;
}
int OutQueue(CyQueue &Q,int a)
{
return Q.data[a];
}
void yanghui(CyQueue &Q){
int a;
scanf("%d",&a);
int i,j,b,c,d=0;
for(i=0;i<a;i++)
{
for(j=0;j<i+1;j++)
{
if(j==0)
{
b=1;
printf("%d ",b);
InQueue(Q,b);
}
else if(j==i)
{
b=1;
printf("%d ",b);
InQueue(Q,b);
}
else{
b=OutQueue(Q,d+j)+OutQueue(Q,d+j-1);
printf("%d ",b);
InQueue(Q,b);
}
}
printf("\n");
d=d+i;
}
}
int main()
{
printf("请输入行数:\n");
CyQueue Q;
InitQueue(Q);
yanghui(Q);
}
用递归实现:
#include<stdio.h>
#include<stdlib.h>
int yanghui(int i,int j)
{
if(i==j||j==1){
return 1;
}
else{
return (yanghui(i-1,j-1)+yanghui(i-1,j));
}
}
int main()
{
int i,j,k,n;
printf("请输入杨辉三角的层数:\n");
scanf("%d",&n);
for(i=1;i<=n;i++){
for(j=1;j<=i;j++){
printf("%d ",yanghui(i,j));
}
printf("\n");
}
return 0;
}
选做 题目:假设迷宫由m行n列构成,有一个入口和一个出口,入口坐标为(1,1),出口坐标为(m,n),试找出一条从入口通往出口的最短路径。设计算法并编程输出一条通过迷宫的最短路径或报告一个“无法通过”的信息。
一、需求分析
- 随机生成迷宫,用#表示边界和不通,用空格表示可通的路径
- 程序命令执行:
生成迷宫,
打印迷宫,
查找路径
输出路径
- 测试数据:
无
二、概要设计
1. 抽象数据类型定义
为实现上述程序功能,需要一个抽象数据类型:
ADT Graph{
基本操作:
InitQueue(queue &s)
操作结果:队列初始化
InitStack(stack &stack)
操作结果:栈初始化
Push(stack &stack,pos a)
操作结果:将数据入栈
pop(stack &s)
操作结果:出栈
InputQueue(queue &a,pos m)
操作结果:入队列
OutputQueue(queue &a)
操作结果:出队列
Printmap(map a)
操作结果:打印地图
Creatmap(map &a)
操作结果:地图的生成
print(queue a,map &s,stack &b)
操作结果:路径的输出
Findway(map &a,queue &s)
操作结果:路径的查询
- 程序模块:主函数
Int main(){
地图创建;
生成地图;
地图输出;
队列创建;
队列初始化;
栈创建;
栈初始化;
查找路径;
输出可通过的路径地图;
}
三、详细设计
1.数据结构体类型:typedef struct{
int x,y,data;
int last,flag;
}pos;
typedef struct{//栈,pos型
pos *base;//栈底指针
pos *top;//栈顶指针
int stacksize;
}stack;
typedef struct{//地图
pos poses[10][10];
}map;
typedef struct{//队列
pos *elem;
int front,rear;//队头和队尾
}queue;
int InitQueue(queue &s)
int InitStack(stack &stack)
int Push(stack &stack,pos a)
pos pop(stack &s)
void InputQueue(queue &a,pos m)
pos OutputQueue(queue &a)
int length(queue a)
int empty(queue a)
void Printmap(map a)
void Creatmap(map &a)
int print(queue a,map &s,stack &b)
int Findway(map &a,queue &s)
2.主函数
int main(){
map a;
stack S;
queue s;
Creatmap(a);
Printmap(a);
InitStack(S);
InitQueue(s);
int m = Findway(a,s);
if(m){
print(s,a,S);
Printmap(a);
}
else{
printf("No Path");
}
return 0;
}
四、调试分析
1.初次执行存在很多报错,有一些很基础的被我忽略,如调用时并未采用&,导致更改以后的数据并未能成功输出。
2.执行时有的路径生成错误根本无法到达终点的也给输出了,经分析是查找路径子函数里面出现了错误,入队列也存在一定的问题,改正里面的循环以及判断语句,改正如下:for(count=0;count<8;count++){
int x1 = t.x+x[count];
int y1 = t.y+y[count];
if(a.poses[x1][y1].data==0 && a.poses[x1][y1].flag==0){
a.poses[x1][y1].flag = 1;//标记已入队
a.poses[x1][y1].last = m;
InputQueue(s,a.poses[x1][y1]);
if(a.poses[x1][y1].x==8 && a.poses[x1][y1].y==8){
return 1;
}
}
}
3.经过分析时间复杂度为O(n*m)即行列相乘
五、用户手册
1. 本程序的运行环境为DOS操作系统,执行文件为:main.exe。
2. 进入演示程序后即显示文本方式的用户界面。
3. 程序运行后,输出随机生成的地图以及路径和路径地图
六、测试结果
七、附录
源代码:include<stdio.h>
#include<stdlib.h>
#include<time.h>
#define MAXSIZE 100
#define MAXSIZE1 50
typedef struct{
int x,y,data;
int last,flag;
}pos;
typedef struct{//栈
pos *base;//栈底指针
pos *top;//栈顶指针
int stacksize;
}stack;
typedef struct{//地图
pos poses[10][10];
}map;
typedef struct{//队列
pos *elem;
int front,rear;//队头和队尾
}queue;
int InitQueue(queue &s){//初始化队列
s.rear = s.front = 0;
s.elem = (pos*)malloc(100*sizeof(pos));//设置队长最大为100
return 0;
}
int InitStack(stack &stack){//初始化栈
stack.base = (pos*)malloc(MAXSIZE1*sizeof(pos));
stack.top = stack.base;
stack.stacksize = MAXSIZE1;
return 0;
}
int Push(stack &stack,pos a){
if(stack.top-stack.base >= stack.stacksize){
stack.base = (pos*)realloc(stack.base,
(stack.stacksize+MAXSIZE1) * sizeof (pos) );
stack.top = stack.base + stack.stacksize;
stack.stacksize += MAXSIZE1;
}
*(stack.top) = a;
stack.top++;
return 0;
}
pos pop(stack &s){//出栈
return *--s.top;
}
void InputQueue(queue &a,pos m){
if(100 == a.front+1){
printf("队满");
exit(-1);
}else{
a.elem[a.rear++] = m;
}
}
pos OutputQueue(queue &a){//出队
if(a.front == a.rear){
printf("队为空");
exit(-1);
}
return a.elem[a.front++];
}
int length(queue a){//返回队伍长度
return a.rear-a.front;
}
int empty(queue a){
if(length(a)==0){
return 1;
}
return 0;
}
void Printmap(map a){//打印地图
for(int i=0;i<10;i++){
for(int j=0;j<10;j++){
if(a.poses[i][j].data==1){
printf("%2c",'#');
}
else if(a.poses[i][j].data==0){
printf("%2c",' ');
}
else{
printf("%2c",'*');
}
}
printf("\n");
}
}
void Creatmap(map &a){//随机产地图
for(int i=0;i<10;i++){
for(int j=0;j<10;j++){
if(i==0 || i==9 || j==0 || j==9){
a.poses[i][j].data = 1;
}
else{
a.poses[i][j].data = 0;
}
a.poses[i][j].flag = 0;
a.poses[i][j].last = -2;
a.poses[i][j].x = i;
a.poses[i][j].y = j;
}
}
int a1;
srand(time(NULL));
for(int i=1;i<9;i++){
for(int j=1;j<9;j++){
a1=rand()%(3);
if(a1<2){
a.poses[i][j].data = 0;
}else{
a.poses[i][j].data = 1;
}
}
}
a.poses[1][1].data = 0;
a.poses[8][8].data = 0;
}
int print(queue a,map &s,stack &b){//输出路径
int i = a.rear-1;
printf("\n路径为: ");
while(i>0){
Push(b,a.elem[i]);//进栈
s.poses[a.elem[i].x][a.elem[i].y].data = 2;
i = a.elem[i].last;
}
Push(b,a.elem[i]);
s.poses[a.elem[i].x][a.elem[i].y].data = 2;
int count =b.top-b.base;
for(i=0;i<count-1;i++){
pos t = pop(b);
printf("(%d,%d)->",t.x,t.y);
}
pos t = pop(b);
printf("(%d,%d)\n\n",t.x,t.y);
return 0;
}
int Findway(map &a,queue &s){ //查找路径
int i = 1, j = 1,count,m = 0,flag = 0 ;
int x[8] = {1,1,1,0,-1,-1,-1,0};
int y[8] = {1,0,-1,-1,-1,0,1,1};
a.poses[1][1].flag = 1;
a.poses[1][1].last = -1;
InputQueue(s,a.poses[1][1]);
while(1){
flag = 0;
pos t = OutputQueue(s);//出列
for(count=0;count<8;count++){
int x1 = t.x+x[count];
int y1 = t.y+y[count];
if(a.poses[x1][y1].data==0 && a.poses[x1][y1].flag==0){
a.poses[x1][y1].flag = 1;//标记已入队
a.poses[x1][y1].last = m;
InputQueue(s,a.poses[x1][y1]);
if(a.poses[x1][y1].x==8 && a.poses[x1][y1].y==8){
return 1;
}
}
}
m++;
if(empty(s)){
return 0;
}
}
}
int main(){
map a;
stack S;
queue s;
Creatmap(a);
Printmap(a);
InitStack(S);
InitQueue(s);
int m = Findway(a,s);
if(m){
print(s,a,S);
Printmap(a);
}
else{
printf("无路径");
}
return 0;
}