实验一栈和队列的应用
- 格式:pdf
- 大小:240.84 KB
- 文档页数:14
栈和队列的实验报告栈和队列的实验报告引言:栈和队列是计算机科学中常用的数据结构,它们在算法设计和程序开发中起着重要的作用。
本实验旨在通过实际操作和观察,深入理解栈和队列的概念、特点以及它们在实际应用中的作用。
一、栈的实验1.1 栈的定义和特点栈是一种具有特殊操作约束的线性数据结构,它的特点是“先进后出”(Last-In-First-Out,LIFO)。
栈的操作包括入栈(push)和出栈(pop),入栈操作将元素放入栈顶,出栈操作将栈顶元素移除。
1.2 实验步骤在本次实验中,我们使用编程语言实现了一个栈的数据结构,并进行了以下实验步骤:1.2.1 创建一个空栈1.2.2 向栈中依次压入若干元素1.2.3 查看栈顶元素1.2.4 弹出栈顶元素1.2.5 再次查看栈顶元素1.3 实验结果通过实验,我们观察到栈的特点:最后入栈的元素最先出栈。
在实验步骤1.2.2中,我们依次压入了元素A、B和C,栈顶元素为C。
在实验步骤1.2.4中,我们弹出了栈顶元素C,此时栈顶元素变为B。
二、队列的实验2.1 队列的定义和特点队列是一种具有特殊操作约束的线性数据结构,它的特点是“先进先出”(First-In-First-Out,FIFO)。
队列的操作包括入队(enqueue)和出队(dequeue),入队操作将元素放入队尾,出队操作将队头元素移除。
2.2 实验步骤在本次实验中,我们使用编程语言实现了一个队列的数据结构,并进行了以下实验步骤:2.2.1 创建一个空队列2.2.2 向队列中依次插入若干元素2.2.3 查看队头元素2.2.4 删除队头元素2.2.5 再次查看队头元素2.3 实验结果通过实验,我们观察到队列的特点:最先入队的元素最先出队。
在实验步骤2.2.2中,我们依次插入了元素X、Y和Z,队头元素为X。
在实验步骤2.2.4中,我们删除了队头元素X,此时队头元素变为Y。
三、栈和队列的应用栈和队列在实际应用中有广泛的应用场景,下面简要介绍一些常见的应用:3.1 栈的应用3.1.1 表达式求值:通过栈可以实现对表达式的求值,如中缀表达式转换为后缀表达式,并计算结果。
实验二(1)1实验题目: 栈和队列的应用2实验内容: 迷宫问题3实验目的: 掌握栈和队列的概念及工作原理,运用其原理完成 实验题目中的内容。
4实验要求: 为了使学生更好的掌握与理解课堂上老师所讲的概 念与原理,实验前每个学生要认真预习所做的实验 内容及编写源程序代码(写在纸上与盘中均可),以 便在实验课中完成老师所布置的实验内容5设计原理:6程序清单及注释说明:#include<stdio.h>#include<stdlib.h>#define M 15#define N 15定义迷宫内点的坐标类型struct mark //{int x;int y;};恋"栈元素,嘿嘿。
struct Element //"{行,y列int x,y; //x下一步的方向int d; //d};链栈typedef struct LStack //{Element elem;struct LStack *next;}*PLStack;/*************栈函数****************/构造空栈int InitStack(PLStack &S)//{S=NULL;return 1;}int StackEmpty(PLStack S)//判断栈是否为空{if(S==NULL)return 1;elsereturn 0;}int Push(PLStack &S, Element e)//压入新数据元素 {PLStack p;p=(PLStack)malloc(sizeof(LStack));p->elem=e;p->next=S;S=p;return 1;}int Pop(PLStack &S,Element &e) //栈顶元素出栈 {PLStack p;if(!StackEmpty(S)){e=S->elem;p=S;S=S->next;free(p);return 1;}elsereturn 0;}/***************求迷宫路径函数***********************/void MazePath(struct mark start,struct mark end,int maze[M][N],int diradd[4][2]) {int i,j,d;int a,b;Element elem,e;PLStack S1, S2;InitStack(S1);InitStack(S2);入口点作上标记maze[start.x][start.y]=2; //elem.x=start.x;elem.y=start.y;elem.d=-1; //开始为-1Push(S1,elem);栈不为空 有路径可走while(!StackEmpty(S1)) //{Pop(S1,elem);i=elem.x;j=elem.y;d=elem.d+1; //下一个方向试探东南西北各个方向while(d<4) //{a=i+diradd[d][0];b=j+diradd[d][1];如果到了出口if(a==end.x && b==end.y && maze[a][b]==0) //{elem.x=i;elem.y=j;elem.d=d;Push(S1,elem);elem.x=a;elem.y=b;elem.d=886; //方向输出为-1 判断是否到了出口Push(S1,elem);东 1=南 2=西 3=北 886为则走出迷宫\n\n通路为:(行坐标,列坐标,方向)\n"); printf("\n0=逆置序列 并输出迷宫路径序列while(S1) //{Pop(S1,e);Push(S2,e);}while(S2){Pop(S2,e);printf("-->(%d,%d,%d)",e.x,e.y,e.d);}跳出两层循环,本来用break,但发现出错,exit又会结束程序,选用return还是不return; //错滴o(∩_∩)o...}if(maze[a][b]==0) //找到可以前进的非出口的点{标记走过此点maze[a][b]=2; //elem.x=i;elem.y=j;elem.d=d;Push(S1,elem); //当前位置入栈下一点转化为当前点i=a; //j=b;d=-1;}d++;}}没有找到可以走出此迷宫的路径\n");printf("}建立迷宫*******************//*************void initmaze(int maze[M][N]){int i,j;迷宫行,列int m,n; //请输入迷宫的行数 m=");printf("scanf("%d",&m);请输入迷宫的列数 n=");printf("scanf("%d",&n);请输入迷宫的各行各列:\n用空格隔开,0代表路,1代表墙\n",m,n);printf("\nfor(i=1;i<=m;i++)for(j=1;j<=n;j++)scanf("%d",&maze[i][j]);printf("\n");你建立的迷宫为o(∩_∩)o...加一圈围墙for(i=0;i<=m+1;i++) //{maze[i][0]=1;maze[i][n+1]=1;}for(j=0;j<=n+1;j++){maze[0][j]=1;maze[m+1][j]=1;}输出迷宫for(i=0;i<=m+1;i++) //{for(j=0;j<=n+1;j++)printf("%d ",maze[i][j]);printf("\n");}}void main(){int sto[M][N];入口和出口的坐标struct mark start,end; //start,end行增量和列增量 方向依次为东西南北 int add[4][2]={{0,1},{1,0},{0,-1},{-1,0}};//建立迷宫initmaze(sto);//输入入口的横坐标,纵坐标[逗号隔开]\n");printf("scanf("%d,%d",&start.x,&start.y);输入出口的横坐标,纵坐标[逗号隔开]\n");printf("scanf("%d,%d",&end.x,&end.y);MazePath(start,end,sto,add); //find pathsystem("PAUSE");}7.运行与测试及结果。
数据结构栈和队列实验报告实验报告:数据结构栈和队列一、实验目的1.了解栈和队列的基本概念和特点;2.掌握栈和队列的基本操作;3.掌握使用栈和队列解决实际问题的方法。
二、实验内容1.栈的基本操作实现;2.队列的基本操作实现;3.使用栈和队列解决实际问题。
三、实验原理1.栈的定义和特点:栈是一种具有后进先出(LIFO)特性的线性数据结构,不同于线性表,栈只能在表尾进行插入和删除操作,称为入栈和出栈操作。
2.队列的定义和特点:队列是一种具有先进先出(FIFO)特性的线性数据结构,不同于线性表,队列在表头删除元素,在表尾插入元素,称为出队和入队操作。
3.栈的基本操作:a.初始化:建立一个空栈;b.入栈:将元素插入栈的表尾;c.出栈:删除栈表尾的元素,并返回该元素;d.取栈顶元素:返回栈表尾的元素,不删除。
4.队列的基本操作:a.初始化:建立一个空队列;b.入队:将元素插入队列的表尾;c.出队:删除队列表头的元素,并返回该元素;d.取队头元素:返回队列表头的元素,不删除。
四、实验步骤1.栈的实现:a.使用数组定义栈,设置栈的大小和栈顶指针;b.实现栈的初始化、入栈、出栈和取栈顶元素等操作。
2.队列的实现:a.使用数组定义队列,设置队列的大小、队头和队尾指针;b.实现队列的初始化、入队、出队和取队头元素等操作。
3.使用栈解决实际问题:a.以括号匹配问题为例,判断一个表达式中的括号是否匹配;b.使用栈来实现括号匹配,遍历表达式中的每个字符,遇到左括号入栈,遇到右括号时将栈顶元素出栈,并判断左右括号是否匹配。
4.使用队列解决实际问题:a.以模拟银行排队问题为例,实现一个简单的银行排队系统;b.使用队列来模拟银行排队过程,顾客到达银行时入队,处理完业务后出队,每个顾客的业务处理时间可以随机确定。
五、实验结果与分析1.栈和队列的基本操作实现:a.栈和队列的初始化、入栈/队、出栈/队以及取栈顶/队头元素等操作均能正常运行;b.栈和队列的时间复杂度均为O(1),操作效率很高。
栈和队列的应用(10003809389j)一实验目的使学生掌握栈的特点及其逻辑结构和物理结构的实现;使学生掌握队列的特点及其逻辑结构和物理结构的实现;使学生掌握链栈和顺序栈结构的插入、删除等基本运算的实现;使学生掌握链队列和顺序队列结构的插入、删除等基本运算的实现;使学生熟练运用栈结构解决常见实际应用问题;使学生熟练运用队列结构解决常见实际应用问题;二实验环境所需硬件环境为微机;所需软件环境为 Microsoft Visual C++ 6.0 ;三实验内容链栈:#include "LinkList0.c"/*详见实验1*/LinkList InitStack_Sl() {LinkList S;S=InitList_Sl();return S; }Status DestroyStack_Sl(LinkList S) {if(!S) return ERROR;/*链栈不存在*/DestroyList_Sl(S);return OK; }Status StackEmpty_Sl(LinkList S) {if(!S) return ERROR;/*链栈不存在*/if(S->next==NULL)return TRUE;elsereturn FALSE; }/*若链栈S存在,则当S非空时返回栈顶元素e */Status StackGetTop_Sl(LinkList S) {if(!S) return ERROR;/*链栈不存在*/if(S->next==NULL) return FALSE;/*栈空*/elsereturn (S->next->elem); }/*若链栈S存在,则当S非空时,删除栈顶元素并用e保存删除的栈顶元素*/ Status StackPop_Sl(LinkList S,ElemType *e) {if(!S) return ERROR;/*链栈不存在*/ListDelete_Sl(S,e);return OK; }/*若链栈S存在时,插入元素e为新的栈顶元素*/Status StackPush_Sl(LinkList S,ElemType e) {if(!S) return ERROR;/*链栈不存在*/ListInsert_Sl(S,e);return OK; }/*若链栈S存在,返回链栈中元素个数*/int StackLength_Sl(LinkList S) {if(!S) return ERROR;/*链栈不存在*/return ListLength_Sl(S); }/*若链栈S存在,遍历链栈S,对每个元素执行操作void(*operate)(ElemType*)*/Status StackTraverse_Sl(LinkList S,void(*operate)(ElemType*)) { if(!S) return ERROR;/*链栈不存在*/return(ListTraverse_Sl(S,operate)); }链队列#include "LinkList0.c"/*详见实验1*/typedef struct Qode{ElemType elem;struct Qode *next;} Qode,*Queue;typedef struct {Queue front;Queue rear;}Linkqueue, *LinkQueue;/*InitQueue_Sq()构造一个空的队列*/LinkQueue InitQueue_Sl() {LinkQueue Q;Q->front=Q->rear=(Queue)malloc(sizeof(Qode));if(!Q->front) return NULL;/*存储分配失败*/Q->front->next=NULL;return Q; }/*若队列Q存在,销毁链队列Q*/Status DestroyQueue_Sl(LinkQueue Q) {Queue p;if(!Q) return ERROR;/*链队列不存在*/do{ /*释放单向线性链表空间*/p=Q->front;Q->front=Q->front->next;free(p);}while(Q->front);return OK; }/*若链队列Q存在,则当Q为空时返回TRUE,否则返回FALSE*/Status QueueEmpty_Sl(LinkQueue Q) {if(!Q) return ERROR;/*链队列不存在*/if(Q->front==Q->rear)return TRUE;elsereturn FALSE; }/*若链队列Q存在,则当Q非空时,返回队头元素e */Status QueueGetTop_Sl(LinkQueue Q,ElemType e) {if(!Q) return ERROR;/*链队列不存在*/if(QueueEmpty_Sl(Q)==TRUE) return FALSE;/*队列空*/else return (Q->front->next->elem); }/*若链队列Q存在,则当Q非空时,删除队头元素并用e保存删除的队头元素*/ Status DeQueue_Sl(LinkQueue Q,ElemType *e) {Queue p;if(!Q) return ERROR;/*顺序队列不存在*/if(QueueEmpty_Sl(Q)==TRUE) return FALSE;/*队列空*/else{p=Q->front->next;*e=p->elem;Q->front->next=p->next;if(Q->front->next==NULL) Q->rear=Q->front;free(p);return OK; } }/*若链队列Q存在时,插入元素e为新的队头元素*/ Status EnQueue_Sl(LinkQueue Q,ElemType e) {Queue p;if(!Q) return ERROR;/*单向线性链表结点L不存在*/ p=(Queue)malloc(sizeof(Qode));if(!p) exit(OVERFLOW); /*存储空间增加失败*/p->next=NULL;p->elem=e;Q->rear->next=p;Q->rear=p;return OK; }/*若链队列Q存在,返回链队列元素个数*/int QueueLength_Sl(LinkQueue Q) {int i=0;Queue p;if(!Q) return ERROR;/*链队列不存在*/p=Q->front;while(p!=Q->rear){ i++;p=p->next; }return (i); }/*若链队列Q存在,遍历链队列Q,对每个元素执行操作void(*operate)(ElemType*)*/ Status QueueTraverse_Sl(LinkQueue Q,void(*operate)(ElemType*)) {Queue p;if(!Q) return ERROR;/*链队列不存在*/p=Q->front->next;while(p!=NULL){ operate(&p->elem);p=p->next; }return(OK); }表达式求解#include "LinkStack.c"//用链栈实现中缀表达式求解。
《数据结构》第五次实验报告学生姓名学生班级学生学号指导老师雷大江重庆邮电大学计算机学院一、实验内容1) 利用栈深度优先进行迷宫求解。
用数组表示迷宫建立栈,利用栈实现深度优先搜索2) 利用队列宽度优先进行迷宫求解。
用数组表示迷宫建立队列,利用队列实现宽度优先搜索二、需求分析利用栈的结构,走过的路入栈,如果不能走出栈,采用遍历法,因此栈内存储的数据就是寻一条路径。
当到达了某点而无路可走时需返回前一点,再从前一点开始向下一个方向继续试探。
因此,压入栈中的不仅是顺序到达的各点的坐标,而且还要有从前一点到达本点的方向,即每走一步栈中记下的内容为(行,列,来的方向)。
三、详细设计(1)基本代码struct item{int x ; //行int y ; //列} ;item move[4] ;(2)代码栈构造函数:void seqstack::Push(int x,int y,int d) //入栈{if(top>=StackSize-1)throw"上溢";top++;data[top].d=d;data[top].x=x;data[top].y=y;}寻找路径:int seqstack::findpath(int a,int b){item move[4]={{0,1},{1,0},{0,-1},{-1,0}};//定义移动结构int x, y, d, i, j ;Push(a,b,-1); //起点坐标入栈while(top!=-1){d=data[top].d+1;x=data[top].x;y=data[top].y;Pop(); //出栈while (d<4) //方向是否可以移动{i=x+move[d].x ; j=y+move[d].y ; //移动后坐标if(Map[i][j]==0) //是否能移动 {Push(x,y,d); //移动前坐标入栈x=i;y=j;Map[x][y]= -1 ;if(x==m&&y==n) //判断是否为终点坐标 {Push(x,y,-1);return 1 ;}else d=0 ;}else d++ ;}}return 0;}(3)伪代码a)栈初始化;b)将入口点坐标及到达该点的方向(设为-1)入栈c)while (栈不空){栈顶元素=(x , y , d)出栈 ;求出下一个要试探的方向d++ ;while (还有剩余试探方向时){ if (d方向可走)则 { (x , y , d)入栈 ;求新点坐标 (i, j ) ;将新点(i , j)切换为当前点(x , y) ;if ( (x ,y)= =(m,n) ) 结束 ;else 重置 d=0 ;}else d++ ;}}(4)时间复杂程度时间复杂程度为O(1)2.3 其他在运行时可选择是否自己构造地图,实现函数如下:void creatmap() //自创地图函数{for(int i=1;i<9;i++){for(int j=1;j<9;j++)Map[i][j]=0;}Map[8][9]=1;printmap();cout<<"请设置障碍物位置:(x,y)。
数据结构栈与队列的实验报告实验概述本次实验的目的是通过对栈和队列进行实现和应用,加深对数据结构中的栈和队列的理解和巩固操作技能。
栈和队列作为常见的数据结构在程序开发中得到了广泛的应用,本次实验通过 C++ 语言编写程序,实现了栈和队列的基本操作,并对两种数据结构进行了应用。
实验内容1. 栈的实现栈是一种先进后出的数据结构,具有后进先出的特点。
通过使用数组来实现栈,实现入栈、出栈、输出栈顶元素和清空栈等操作。
对于入栈操作,将元素插入到数组的栈顶位置;对于出栈操作,先将数组的栈顶元素弹出,再使其下移,即将后面的元素全部向上移动一个位置;输出栈顶元素则直接输出数组的栈顶元素;清空栈则将栈中所有元素全部清除即可。
3. 栈和队列的应用利用栈和队列实现八皇后问题的求解。
八皇后问题,是指在8×8 的国际象棋盘上放置八个皇后,使得任意两个皇后都不能在同一行、同一列或者同一对角线上。
通过使用栈来保存当前八皇后的位置,逐个放置皇后并检查是否有冲突。
如果当前位置符合要求,则将位置保存到栈中,并继续查询下一个皇后的位置。
通过使用队列来进行八数码问题的求解。
八数码问题,是指在3×3 的矩阵中给出 1 至 8 的数字和一个空格,通过移动数字,最终将其变为 1 2 3 4 5 6 7 8 空的排列。
通过使用队列,从初始状态出发,枚举每种情况,利用队列进行广度遍历,逐一枚举状态转移,找到对应的状态后进行更新,周而复始直到找到正确的答案。
实验结果通过使用 C++ 语言编写程序,实现了栈和队列的基本操作,并对八皇后和八数码问题进行了求解。
程序执行结果如下:栈和队列实现的基本操作都能够正常进行,并且运行效率较高。
栈和队列的实现方便了程序编写并加速了程序运行。
2. 八皇后问题的求解通过使用栈来求解八皇后问题,可以得到一组成立的解集。
图中展示了求解某一种八皇后问题的过程。
从左到右是棋盘的列数,从上到下是棋盘的行数,通过栈的操作,求出了在棋盘上符合不同要求(不在同一行、同一列和斜线上)的八皇后位置。
实验一栈和队列的应用一、实验目的1、掌握栈的编写和应用2、掌握队列的编写和应用二、实验内容1、分别使用STL中的栈和自己编写的栈类,实现序列的反转(1)简单修改下面代码,实现使用STL中的栈进行序列的反转,编译运行#include <stack>int main( )/* Pre: The user supplies an integer n and n decimal numbers.Post: The numbers are printed in reverse order.Uses: The STL class stack and its methods */{int n;double item;stack<double> numbers; // declares and initializes a stack of numberscout << " Type in an integer n followed by n decimal numbers."<< endl<< " The numbers will be printed in reverse order."<< endl;cin >> n;for (int i = 0; i < n; i++) {cin >> item;numbers.push(item);}cout << endl << endl;while (!numbers.empty( )) {cout << numbers.top( ) << " ";numbers.pop( );}cout << endl;}提示:(1)由于程序是用了STL(标准模板库,可以简单的看成是一个函数库,在其中有各种有用的类、函数和算法),栈在其中有实现。
栈和队列应用案例栈和队列是计算机科学中常用的数据结构,它们具有各自独特的特性和应用场景。
栈是一种后进先出(LIFO)的数据结构,而队列则是一种先进先出(FIFO)的数据结构。
本文将介绍栈和队列的应用案例,并分析它们在实际问题中的使用。
一、栈的应用案例1. 后退和前进功能在浏览器中,我们经常使用后退和前进按钮来切换网页。
这种功能可以通过一个栈来实现。
每当我们访问一个新的网页时,将当前的网页URL压入栈中。
当我们点击后退按钮时,可以从栈中弹出上一个URL,实现后退功能。
当我们点击前进按钮时,可以从另一个栈中弹出下一个URL,实现前进功能。
2. 括号匹配在编程语言中,括号匹配是一种常见的问题。
我们可以使用栈来解决括号匹配的问题。
遍历字符串,当遇到左括号时,将其压入栈中;当遇到右括号时,从栈中弹出一个元素,并判断是否与当前右括号匹配。
如果栈为空或出现不匹配的情况,则说明括号不匹配。
3. 逆波兰表达式逆波兰表达式是一种将运算符号放在操作数之后的数学表达式表示方式。
使用栈可以轻松计算逆波兰表达式。
遍历逆波兰表达式,当遇到数字时,将其压入栈中;当遇到运算符时,从栈中弹出两个数字进行计算,并将结果压入栈中。
最终,栈中剩下的数字即为逆波兰表达式的计算结果。
二、队列的应用案例1. 银行排队在银行办理业务时,通常需要排队等待。
这可以通过队列来实现。
当顾客到达银行时,将其加入队列的末尾。
当柜台有空余时,从队列的头部取出一个顾客进行业务办理。
这种方式可以保证先来的顾客先办理业务,实现公平的排队系统。
2. 多线程任务调度在多线程编程中,任务调度是一个重要的问题。
队列可以用于实现任务的调度和执行。
将需要执行的任务加入队列中,每个线程从队列中取出一个任务进行处理。
这种方式可以充分利用系统资源,实现高效的任务并行处理。
3. 数据缓存队列还可用于数据缓存。
当有大量数据需要处理时,可以将数据加入队列中,然后由单独的线程从队列中取出数据进行处理。
1、栈和队列的应用一、实验目的:(从下面3道题中任选1题完成)(1)利用栈实现迷宫的求解(2)利用堆栈实现计算器(3)实现贪食蛇游戏二、实验内容1、迷宫的求解:迷宫问题是栈应用的一个典型例子。
求解过程可采用回溯法。
回溯法是一种不断试探且及时纠正错误的搜索方法。
从入口出发,按某一方向向前探索,若能走通(未走过的),即某处可以到达,则到达新点,否则试探下一方向 ; 若所有的方向均没有通路,则沿原路返回前一点,换下一个方向再继续试探,直到所有可能的通路都探索到,或找到一条通路,或无路可走又返回到入口点。
在求解过程中,为了保证在到达某一点后不能向前继续行走(无路)时,能正确返回前一点以便继续从下一个方向向前试探,则需要用一个栈保存所能够到达的每一点的下标及从该点前进的方向,栈中保存的就是一条迷宫的通路。
迷宫算法:if(向上位置可通){把向上位置编号加入堆栈;往上走;判断是否为出口;}else if(向下位置可通){把向下位置编号加入堆栈;往下走;判断是否为出口;}else if(向左位置可通){把向左位置编号加入堆栈;往左走;判断是否为出口;}else if(向右位置可通){把向右位置编号加入堆栈;往右走;判断是否为出口;}else{从堆栈删除栈顶编号;取得栈顶编号;往回走;}栈抽象数据类型:typedef struct{pathindex[StackSize];inttop;int}MazeStack;堆栈基本操作:void InitStack(MazeStack *maze) //构建一个空栈int Push(MazeStack *maze, int index) //插入编号index为新的栈顶元素int Pop(MazeStack *maze) //删除栈顶元素,并返回其置int GetTop(MazeStack maze) //返回栈顶元素void Print(MazeStack maze)//从栈底到栈顶依次遍历堆栈输出每个元素迷宫实现实例思想:int maze[rows*cols]={0,0,0,0,0,0,0,0,0,0, //第一列2,1,1,0,1,1,1,0,1,0, //第二列0,0,1,0,1,1,1,0,1,0, //第三列0,1,1,1,1,0,0,1,1,0, //第四列0,1,0,0,0,1,1,1,1,0, //第五列0,1,1,1,0,1,1,1,1,3, //第六列0,1,0,1,1,1,0,1,1,0, //第七列0,1,0,0,0,1,0,0,1,0, //第八列0,0,1,1,1,1,1,1,1,0, //第九列0,0,0,0,0,0,0,0,0,0};//第十列int record[rows*cols];int nowPos,prePos;bool find=false;int rowNum,colNum;int up,down,left,right;说明:常数rows与cols分别代表迷宫的行数和列数,nowPos用来记录当前位置编号,prePos则是上一步位置编号,布尔变量find用来记录是否找到迷宫出口,堆栈用来记录移动路径,建立迷宫地图maze[]数组,元素0,1,2,3分别代表迷宫的墙,通道,入口和出口,数组record[]用来记录迷宫不可通过的墙及已走过的路径。
for (int i=0;i<rows*cols;i++){maze[i];=record[i]2)==if(maze[i]{nowPos = i;Push(&m,i);record[i] = 0;nowPos=i;}}//给record[]数组赋值,并找到入口编号加入堆栈,并赋值给nowPos While(!find){up = nowPos - cols; //当前上方位置在数组中的编号down = nowPos + cols; //当前下方位置在数组中的编号left = nowPos - 1; //当前左方位置在数组中的编号right = nowPos + 1; //当前右方位置在数组中的编号rowNum=nowPos/cols;//当前位置在数组中的编号转换成二维坐标colNum=nowPos%cols;if(向上位置可通){把向上位置编号加入堆栈;往上走;判断是否为出口;}if(向下位置可通){…}if(向左位置可通){…}if(向右位置可通) {…}else{从堆栈删除栈顶编号;取得栈顶编号;往回走;}}实现效果参考:2、计算器的实现:运算符的优先级处理和算术表达式的计算表达式求值是程序设计语言编译中的一个最基本问题。
它的实现是栈应用的又一个典型例子。
这里介绍一种简单直观、广为使用的算法,通常称为“算符优先法”。
要把一个表达式翻译成正确求值的一个机器指令序列,或者直接对表达式求值,首先要能够正确解释表达式。
例如,要对下面的算术表达式求值:4 + 2 × 3 - 10/5首先要了解算术四则运算的规则。
即:(1)先乘除,后加减;(2)从左算到右;(3)先括号内,后括号外。
由此,这个算术表达式的计算顺序应为4 + 2 × 3 - 10/5 = 4 +6 - 10/5 = 10 - 10/5 = 10 - 2 = 8算符优先法就是根据这个运算优先关系的规定来实现对表达式的编译或解释执行的。
任何一个表达式都是由操作数(operand)、运算符(operator)和界限符(delimiter)组成的,我们称它们为单词。
一般地,操作数既可以是常数也可以是被说明为变量或常量的标识符;运算符可以分为算术运算符、关系运算符和逻辑运算符3类;基本界限符有左右括号和表达式结束符等。
为了叙述的简洁,我们仅讨论简单算术表达式的求值问题。
这种表达式只含加、减、乘、除4种运算符。
不难将它推广到更一般的表达式上。
我们把运算符和界限符统称为算符,它们构成的集合命名为OP。
根据上述3条运算规则,在运算的每一步中,任意两个相继出现的算符θ1和θ2之间的优先关系至多是下面3种关系之一:θ1<θ2 θ1的优先权低于θ2θ1=θ2 θ1的优先权等于θ2θ1>θ2 θ1的优先权高于θ2表1定义了算符之间的这种优先关系。
由规则(3),+、-、*和/为θ1时的优先性均低“(”但高于“)”,由规则(2),当θ1=θ2时,令θ1>θ2,“#”是表达式的结束符。
为了算法简洁,在表达式的最左边也虚设一个“#”构成整个表达式的一对括号。
表中的“(”=“)”表示当左右括号相遇时,括号内的运算已经完成。
同理,“#”=“#”表示整个表达式求值完毕。
“)”与“(”、“#”与“)”以及“(”与“#”之间无优先关系,这是因为表达式中不允许它们相继出现,一旦遇到这种情况,则可以认为出现了语法错误。
在下面的讨论中,我们暂假定所输入的表达式不会出现语法错误。
为实现算符优先算法,可以使用两个工作栈。
一个称做OPTR,用以寄存运算符;另一个称做OPND,用以寄存操作数或运算结果。
算法的基本思想的:(1)首先置操作数栈为空栈,表达式起始符“#”为运算符栈的栈底元素;(2)依次读入表达式中每个字符,若是操作数则进 OPND 栈,若是运算符则和OPTR 栈的栈顶运算符比较优先权后作相应操作,直至整个表达式求值完毕(即OPTR 栈的栈顶元素和当前读入的字符均为“#”)。
以下算法描述了这个求值过程。
相应的函数:堆栈初始化void Init_OPND(OPND *ds)入栈void PushData(OPND *ds,int e)出栈int PopData(OPND *ds)取栈顶元素int GetTopData(OPND *ds)存储结构:typedef struct{a[MAXSIZE];inttop;int}OPND;算符优先级关系:判断是否操作符int IsOpr(char c)if(c=='+'||c=='-'||c=='*'||c=='/'||c=='('||c==')'||c=='='||c=='#') return 1;else return 0;判断优先级char Precede(char s,char c)switch(s){ case '+':'-':caseif(c=='+'||c=='-') return '>';else if(c=='*'||c=='/') return '<';else if(c=='(') return '<';else if(c==')') return '>';else return '>';case '*':case '/':…..}两数进行操作int Operate(int x, char opr, int y)int result;switch (opr){ case '+':result = x + y;break;'-':caseresult = x - y;break;….}表达式求值过程:OPND sdata;OPTR soper;Init_OPND(&sdata);Init_OPTR(&soper);PushOper(&soper,'#');scanf("%c",&ch);while(ch!='#'||GetTopOper(&soper)!='#') if(!IsOpr(ch)){..}else{switch(Precede(GetTopOper(&soper),ch)) case '<':{….}case ‘=':{….}case ‘>':{….}}printf("%d\n",GetTopData(&sdata));实现效果参考:3、实现贪食蛇游戏实现效果参考:要求:1)能用键盘控制蛇的移动2)能实现蛇吃了食物以后,蛇身能够增长3)能随机产生食物,并且产生食物位置不在蛇身上4)需要对蛇出界的时候做出相应的处理三、实验内容1、利用栈实现迷宫的求解2、利用堆栈实现计算器3、实现贪食蛇游戏四、实验评分标准:1、实现基本算法的求解(+70分)2、实现可视化界面(+30分)提示:可采用vb, java, dephi, vc6.0(win32 application or mfc), .net实现可视化界面,本课程推荐使用vc6.0(win32 application or mfc), .net实现五、参考教材1、Visual C++ 游戏编程基础,肖永亮丛书主编,荣欣科技著,电子工业出版社2、深入浅出MFC 第2版,作者:侯俊杰(侯捷),出版社:华中科技大学出版社。