数据结构实验二
数据结构实验报告(C语言)(强力推荐)
数据结构实验实验内容和目的:掌握几种基本的数据结构:集合、线性结构、树形结构等在求解实际问题中的应用,以及培养书写规范文档的技巧。
学习基本的查找和排序技术。
让我们在实际上机中具有编制相当规模的程序的能力。
养成一种良好的程序设计风格。
实验教材:数据结构题集(C语言版)清华大学出版社2007年实验项目:实验一、栈和循环队列㈠、实验内容:①栈掌握栈的特点(先进后出FILO)及基本操作,如入栈、出栈等,栈的顺序存储结构和链式存储结构,以便在实际问题背景下灵活应用。
本程序采用的是链栈结构,具有初始化一个栈、PUSH、POP、显示所有栈里的元素四个功能。
②循环队列掌握队列的特点(先进先出FIFO)及基本操作,如入队、出队等,学会循环队列的实现,以便在实际问题背景下灵活运用。
本程序具有初始化一个队列、入队、出队、显示队列的所有元素、队列长度五个功能。
㈡、实验代码①栈程序代码:#include <stdio.h>#include <malloc.h>#define Stack_Size 6#define ERROR 0#define OK 1typedef int SElemType;typedef struct SNode{SElemType data;struct SNode *next;}SNode,*LinkStack;int CreatTwo(LinkStack &head,int n){int i;SNode *p;head=(LinkStack)malloc(sizeof(SNode));head->next=NULL;printf("请输入数据(数字):\n");for(i=n;i>0;--i){p=(SNode *)malloc(sizeof(SNode));scanf("%d",&p->data);p->next=head->next;head->next=p;}return 1;}int menu_select(){int sn;for(;;){scanf("%d",&sn);if(sn<1||sn>6)printf("\n\t输入错误,请重新输入\n");elsebreak;}return sn;}int Push(LinkStack &top,SElemType e){SNode *q;q=(LinkStack)malloc(sizeof(SNode));if(!q){printf("溢出!\n");return(ERROR);}q->data=e;q->next=top->next;top->next=q;return(OK);}int Pop(LinkStack &top,SElemType &e){SNode *q;if(!top->next){printf("error!\n");return(ERROR);}e=top->next->data;q=top->next;top->next=q->next;free(q);return(OK);}void main(){ int e;LinkStack top;printf("1.初始化一个栈;\n2.PUSH;\n3.POP;\n4.显示所有栈里的元素;\n5.结束;\n");while(1){switch(menu_select()){case 1:if(CreatTwo(top,Stack_Size))printf("Success!\n");break; case 2:printf("Push:\n");scanf("%d",&e);if(Push(top,e))printf("Success!\n");break;case 3:if(Pop(top,e))printf("Success!\n");printf("%d\n",e);break;case 4:LinkStack p;printf("所有栈里的元素:\n");p=top;while(p->next){p=p->next;printf("%7d",p->data);}printf("\n");break;case 5:return;}}}运行结果:②循环队列程序代码:#include<stdlib.h>#include<stdio.h>#define OVERFLOW -1#define OK 1#define ERROR 0#define MAXSIZE 100typedef struct{int *elem;//队列存储空间int front;int rear;}SqQueue;//判断选择是否正确int menu_select(){int sn;for(;;){scanf("%d",&sn);if(sn<1||sn>6)printf("\n\t输入错误,请重新输入\n");elsebreak;}return sn;}//参数(传出)SqQueue &Q,循环队列(空)int InitQueue(SqQueue &Q){Q.elem=(int *)malloc(MAXSIZE*sizeof(int));if(!Q.elem)exit(OVERFLOW);Q.front=Q.rear=-1;for(int i=0;i<MAXSIZE;i++)Q.elem[i]=-1;return OK;}//返回Q的元素个数int QueueLength(SqQueue Q){return (Q.rear-Q.front+MAXSIZE)%MAXSIZE;}//显示队列的元素void Display(SqQueue Q){for(int i=0;i<=QueueLength(Q);i++)if(Q.elem[i]!=-1)printf("%d ",Q.elem[i]);printf("\n");}//入队int EnQueue(SqQueue &Q,int e){Q.rear=(Q.rear+1)%MAXSIZE;if(Q.rear==Q.front)return ERROR;Q.elem[Q.rear]=e;return OK;}//出队int DeQueue(SqQueue &Q,int &e){if(Q.front==Q.rear)return ERROR;e=Q.elem[Q.front+1];Q.elem[Q.front+1]=-1;Q.front=(Q.front+1)%MAXSIZE;return OK;}void main(){SqQueue Q;InitQueue(Q);int elem,e;printf("请输入队列元素(以0结束):\n");scanf("%d",&elem);while(elem!=0){EnQueue(Q,elem);scanf("%d",&elem);}printf("队列为:\n");Display(Q);printf("1.初始化一个队列;\n2.入队;\n3.出队;\n4.显示队列的所有元素;\n5.队列长度:\n6.结束;\n");while(1){switch(menu_select()){case 1:printf("请输入队列元素(以0结束):\n");scanf("%d",&elem);while(elem!=0){EnQueue(Q,elem);scanf("%d",&elem);}printf("队列为:\n");Display(Q);fflush(stdin);break;case 2:scanf("%d",&elem);EnQueue(Q,elem);printf("队列为:\n");Display(Q);fflush(stdin);break;case 3:DeQueue(Q,elem);printf("队列为:\n");Display(Q);break;case 4:printf("\n队列的所有元素:\n");Display(Q);break;case 5:printf("%d\n",QueueLength(Q));break;case 6:return;}}}运行结果:实验二、数组㈠、实验内容:数组一般不做插入或删除操作,也就是说,一旦建立了数组,则结构中的数据元素个数和元素之间的关系就不再发生变动。
数据结构实验报告实验总结
数据结构实验报告实验总结本次数据结构实验主要涉及线性表、栈和队列的基本操作以及链表的应用。
通过实验,我对这些数据结构的特点、操作和应用有了更深入的了解。
下面对每一部分实验进行总结。
实验一:线性表的基本操作线性表是一种常见的数据结构,本实验要求实现线性表的基本操作,包括插入、删除、查找、遍历等。
在实验过程中,我对线性表的结构和实现方式有了更清晰的认识,掌握了用数组和链表两种方式实现线性表的方法。
实验二:栈的应用栈是一种后进先出(LIFO)的数据结构,本实验要求利用栈实现简单的括号匹配和后缀表达式计算。
通过实验,我了解到栈可以方便地实现对于括号的匹配和后缀表达式的计算,有效地解决了对应的问题。
实验三:队列的应用队列是一种先进先出(FIFO)的数据结构,本实验要求利用队列实现银行排队和迷宫求解。
通过实验,我对队列的应用有了更加深入的了解,了解到队列可以解决需要按顺序处理的问题,如排队和迷宫求解等。
实验四:链表的应用链表是一种常用的数据结构,本实验要求利用链表实现学生信息管理系统。
通过实验,我对链表的应用有了更深入的了解,了解到链表可以方便地实现对于数据的插入、删除和修改等操作,并且可以动态地调整链表的长度,适应不同的需求。
通过本次实验,我掌握了线性表、栈、队列和链表的基本操作,并了解了它们的特点和应用方式。
同时,通过实际编程的过程,我对于数据结构的实现方式和效果有了更直观的认识,也锻炼了自己的编程能力和解决问题的能力。
在实验过程中,我遇到了一些问题,如程序逻辑错误和内存泄漏等,但通过调试和修改,最终成功解决了这些问题,对自己的能力也有了更多的信心。
通过本次实验,我深刻体会到了理论与实践的结合的重要性,也对于数据结构这门课程有了更加深入的理解。
总之,本次数据结构实验给予了我很多有益的启发和收获,对于数据结构的概念、特点和应用有了更深入的理解。
在以后的学习中,我会继续加强对数据结构的学习和研究,不断提高自己的编程能力和解决问题的能力。
数据结构实验指导书(新版)
《数据结构和算法》实验指导书实验及学时数分配序号实验名称学时数(小时)1 实验一线性表 42 实验二树和二叉树 23 实验三图 24 实验四查找 25 实验五内部排序 2合计12几点要求:一、上机前:认真预习相关实验内容,提前编写算法程序,上机时检查(未提前编写程序者,扣除平时成绩中实验相关分数)。
二、上机中:在Turbo C或VC6.0环境中,认真调试程序,记录调试过程中的问题、解决方法以及运行结果。
上机时签到;下机时验收签字。
三、下机后:按要求完成实验报告,并及时提交(实验后1周内)。
实验一线性表【实验目的】1、掌握用Turbo c上机调试线性表的基本方法;2、掌握线性表的基本操作,插入、删除、查找以及线性表合并等运算在顺序存储结构和链式存储结构上的运算;3、运用线性表解决线性结构问题。
【实验学时】4 学时【实验类型】设计型【实验内容】1、顺序表的插入、删除操作的实现;2、单链表的插入、删除操作的实现;3、两个线性表合并算法的实现。
(选做)【实验原理】1、当我们在线性表的顺序存储结构上的第i个位置上插入一个元素时,必须先将线性表中第i个元素之后的所有元素依次后移一个位置,以便腾出一个位置,再把新元素插入到该位置。
若是欲删除第i个元素时,也必须把第i个元素之后的所有元素前移一个位置;2、当我们在线性表的链式存储结构上的第i个位置上插入一个元素时,只需先确定第i个元素前一个元素位置,然后修改相应指针将新元素插入即可。
若是欲删除第i个元素时,也必须先确定第i个元素前一个元素位置,然后修改相应指针将该元素删除即可;3、详细原理请参考教材。
【实验步骤】一、用C语言编程实现建立一个顺序表,并在此表中插入一个元素和删除一个元素。
1、通过键盘读取元素建立线性表;(从键盘接受元素个数n以及n个整形数;按一定格式显示所建立的线性表)2、指定一个元素,在此元素之前插入一个新元素;(从键盘接受插入位置i,和要插入的元素值;实现插入;显示插入后的线性表)3、指定一个元素,删除此元素。
桂电数据结构实验二叉树答案
桂电数据结构实验二叉树答案1. 对于一棵具有n个结点、度为4的树来说,_______________。
[单选题] *A. 树的高度至多是n-3(正确答案)B. 树的高度至多是n-4C. 第i层上至多有4*(i-1)个结点D. 至少在某一层上正好有4个结点2. 一棵完全二叉树上有1001个结点,其中叶子结点的个数是___________。
[单选题] *A. 250B. 501(正确答案)C. 254D. 5053. 在高度为h的完全二叉树中,______________________。
[单选题] *A. 度为0的结点都在第h层上B. 第i (1≤i≤ h)层上结点都是度为2的结点C. 第i (1≤i < h)层上有个结点(正确答案)D. 不存在度为1的结点4. 若二叉树的中序遍历序列是abcdef,且c为根结点,则________________。
[单选题] *A. 结点c有两个孩子(正确答案)B. 二叉树有两个度为0的结点C. 二叉树的高度为5D. 以上都不对5. 在任何一棵二叉树中,如果结点a有左孩子b和右孩子c,则在结点的先序序列、中序序列和后序序列中,___________。
[单选题] *A. 结点b一定在结点a的前面B. 结点a一定在结点c的前面C. 结点b一定在结点c的前面(正确答案)D. 结点a一定在结点b的前面6. 设n、m为一棵二叉树上的两个结点,在中序遍历时,n在m前的条件是___________。
[单选题] *A. n在m的右方B. n是m的祖先C. n在m的左方(正确答案)D. n是m的子孙7. 如果在一棵二叉树的先序序列、中序序列和后序序列中,结点a、b的位置都是a在前、b在后(形如…a…b…),则___________ 。
[单选题] *A. a、b可能是兄弟(正确答案)B. a可能是b的双亲C. a可能是b的孩子D. 不存在这样的二叉树8. 若一棵二叉树具有10个度为2的结点,5个度为1的结点,则度为0的结点个数是_________。
数据结构实验二_栈的基本操作
青岛理工大学课程实验报告及实验步骤只要X不为0重复做下列动作将X%R入栈X=X/R只要栈不为空重复做下列动作栈顶出栈输出栈顶元素调试过程及实验结果根据输入的十进制数通过桟的基本操作可以转换成二进制、八进制、十六进制的数。
在上机过程中程序的调用没有太大的问题,按照课本的基本算法就可以将程序正确的运行。
总结程序可以完成基本的功能,可以将十进制数转换为其他进制的数,基本掌握了桟的几种常用的操作;但程序存在缺陷,就是不能持续进行操作,输入了一个十进制数只能进行一次数制转换,程序就会退出,有待改进。
附录#include <stdio.h>#include <stdlib.h>#include <malloc.h>#define stack_init_size 100#define stackincrement 10typedef struct sqstack{int *base;int *top;int stacksize;} sqstack;int StackInit(sqstack *s){s->base=(int *)malloc(stack_init_size *sizeof(int));if(!s->base)return 0;{return 0;}}int conversion(sqstack *s){int n,e=0,flag=0;printf("输入要转化的十进制数:\n");scanf("%d",&n);printf("要转化为多少进制:2进制、8进制、16进制填数字!\n");scanf("%d",&flag);printf("将十进制数%d转化为%d进制是:\n",n,flag);while(n){s->top=s->base;s->stacksize=stack_init_size;return 1;}int Push(sqstack *s,int e){if(s->top-s->base>=s->stacksize){s->base=(int*)realloc(s->base,(s->stacksize+stackincrement)*sizeof(int)); if(!s->base)return 0;s->top=s->base+s->stacksize;s->stacksize+=stackincrement;}*(s->top++)=e;return e;}int Pop(sqstack *s,int e){if(s->top==s->base)return 0;e=*--s->top;return e;}int stackempty(sqstack *s){if(s->top==s->base){return 1;}elsePush(s,n%flag);n=n/flag;}while(!stackempty(s)) {e=Pop(s,e);switch(e){case 10: printf("A");break;case 11: printf("B");break;case 12: printf("C");break;case 13: printf("D");break;case 14: printf("E");break;case 15: printf("F");break;default: printf("%d",e); }}printf("\n");return 0;}int main(){sqstack s;StackInit(&s); conversion(&s);return 0;}。
数据结构实验指导书(新版)
《数据结构与算法》实验指导书实验及学时数分配几点要求:一、上机前:认真预习相关实验内容,提前编写算法程序,上机时检查(未提前编写程序者,扣除平时成绩中实验相关分数)。
二、上机中:在Turbo C或VC6.0环境中,认真调试程序,记录调试过程中的问题、解决方法以及运行结果。
上机时签到;下机时验收签字。
三、下机后:按要求完成实验报告,并及时提交(实验后1周内)。
实验一线性表【实验目的】1、掌握用Turbo c上机调试线性表的基本方法;2、掌握线性表的基本操作,插入、删除、查找以及线性表合并等运算在顺序存储结构和链式存储结构上的运算;3、运用线性表解决线性结构问题。
【实验学时】4 学时【实验类型】设计型【实验内容】1、顺序表的插入、删除操作的实现;2、单链表的插入、删除操作的实现;3、两个线性表合并算法的实现。
(选做)【实验原理】1、当我们在线性表的顺序存储结构上的第i个位置上插入一个元素时,必须先将线性表中第i个元素之后的所有元素依次后移一个位置,以便腾出一个位置,再把新元素插入到该位置。
若是欲删除第i个元素时,也必须把第i个元素之后的所有元素前移一个位置;2、当我们在线性表的链式存储结构上的第i个位置上插入一个元素时,只需先确定第i个元素前一个元素位置,然后修改相应指针将新元素插入即可。
若是欲删除第i个元素时,也必须先确定第i个元素前一个元素位置,然后修改相应指针将该元素删除即可;3、详细原理请参考教材。
【实验步骤】一、用C语言编程实现建立一个顺序表,并在此表中插入一个元素和删除一个元素。
1、通过键盘读取元素建立线性表;(从键盘接受元素个数n以及n个整形数;按一定格式显示所建立的线性表)2、指定一个元素,在此元素之前插入一个新元素;(从键盘接受插入位置i,和要插入的元素值;实现插入;显示插入后的线性表)3、指定一个元素,删除此元素。
(从键盘接受删除元素位置i,实现删除;显示删除后的线性表)二、用C语言编程实现建立一个单链表,并在此表中插入一个元素和删除一个元素。
北京理工大学数据结构与算法设计实验二
《数据结构与算法设计》实验报告——实验二学院:自动化学院班级:06111001学号:**********姓名:宝竞宇一、实验目的掌握栈的建立,输入,删除,出栈等基本操作。
应用栈解决实际问题。
二、实验内容实现简单计算器的功能,请按照四则运算加、减、乘、除、幂(^)和括号的优先关系和惯例,编写计算器程序。
要求支持运算符:+、-、*、/、%、()和=:①从键盘输入一个完整的表达式,以回车作为表达式输入结束的标志;②输入表达式中的数值均为大于等于零的整数,如果中间计算过程中出现小数也只取整进行计算。
例如,输入:4+2*5= 输出:14输入:(4+2)*(2-10)= 输出:-48三、程序设计1、概要设计抽象数据类型定义:两个栈结构,分别用来储存数据和计算符号宏定义:函数“成功”,“失败的返回值”在主程序程序中先依次输入各表达式,存入相应各栈,然后,调用“判断函数”来判断计算符的优先次序,然后再利用计算函数来计算,表达式值。
其中还有,取栈顶元素函数,存入栈函数。
2、详细设计数据类型实现:struct t{ char dat[200];int top;}prt;入栈函数:存入数组,栈顶指针上移void pushd(long int a){ prd.dat[prd.top++]=a;}出栈:取出对应值,栈顶指针下移long int popd( ){ return prd.dat[--prd.top];}比较优先级:建立数组,比较返回大于小于号。
计算函数:以字符型输入,运算符号,用switch来分支计算判断,返回计算数值long int operation ( long int x, long int y, char a){ s witch(a){ case '+': return x+y;case '-': return x-y;case '*': return x*y;case '/': if ( y )return x/y;else{ printf("Divide 0.\n");return 0;}case '%': return (long int) fmod(x,y);case '^': if (y>=0 ) return (long int) pow(x,y);else return (0);default: printf("Error No. 3\n");return 0;}}主程序:在主程序内,以字符串的形式输入表达式,然后分别调用函数存入各相应栈,然后用数组判断,比较运算符的优先顺序。
数据结构_迷宫求解_实验报告 北邮
数据结构实验报告实验名称:实验二——利用栈结构实现迷宫求解问题学生姓名:班级:班内序号:学号:日期:2012年11月19日一、实验目的1、进一步掌握指针、模板类、异常处理的使用2、掌握栈的操作的实现方法3、掌握队列的操作的实现方法4、学习使用栈解决实际问题的能力5、学习使用队列解决实际问题的能力二、实验要求:利用栈结构实现迷宫求解问题。
迷宫求解问题如下:心理学家把一只老鼠从一个无顶盖的大盒子的入口赶进迷宫,迷宫中设置很多隔壁,对前进方向形成了多处障碍,心理学家在迷宫的唯一出口放置了一块奶酪,吸引老鼠在迷宫中寻找通路以到达出口,测试算法的迷宫如下图所示。
提示:1、可以使用递归或非递归两种方法实现2、老鼠能够记住已经走过的路,不会反复走重复的路径3、可以自己任意设置迷宫的大小和障碍4、使用“穷举求解”的方法三、程序分析1、存储结构栈存储结构;示意图;2、关键算法分析A、绘制迷宫;伪代码:1、输出迷宫的大小及全部设置为障碍;2、根据键盘的输入绘制迷宫的路线,起始点和终点;void draw()//绘制迷宫障碍{k=getch();switch(int(k)){case 105://上if(by>5){by--;j--;}break;case 107://下if(by<M+4){by++;j++;}break;case 106://左if(bx>2){bx=bx-2;i--;}break;case 108://右if(bx<2*N){bx=bx+2;i++;}break;case 114://'R'路map[i][j]=0;cout<<".";break;case 119://'W'墙map[i][j]=-3;cout<<"■";break;case 115://'S'起点s[0].x=i;//起点入栈s[0].y=j;top=1;map[i][j]=-1;cout<<k;break;case 101://'E'终点map[i][j]=-2;cout<<k;break;}gotoxy(bx,by);}B、路径寻找伪代码;1、向某一方向查找是否有路;2、如有遍历一下栈,看是否已经进栈,一进栈就舍弃,寻求下一个;无就让其进栈。
数据结构实验2——栈和队列实验报告
数据结构实验报告实验名称:实验2——栈和队列1 实验目的通过选择下面五个题目之一进行实现,掌握如下内容:进一步掌握指针、模板类、异常处理的使用掌握栈的操作的实现方法掌握队列的操作的实现方法学习使用栈解决实际问题的能力学习使用队列解决实际问题的能力2 实验内容利用栈结构实现八皇后问题。
八皇后问题19世纪著名的数学家高斯于1850年提出的。
他的问题是:在8*8的棋盘上放置8个皇后,使其不能互相攻击,即任意两个皇后都不能处于同一行、同一列、同一斜线上。
请设计算法打印所有可能的摆放方法。
提示:1、可以使用递归或非递归两种方法实现2、实现一个关键算法:判断任意两个皇后是否在同一行、同一列和同一斜线上2. 程序分析主程序:#include<iostream>using namespace std;const int StackSize=8; //皇后的个数int num=0;template <class T>class SeqStack //定义顺序栈模板类{public:SeqStack(){top=-1;} //构造函数,初始化空栈void Push(T x); //入栈操作void Pop();//出栈操作void PlaceQueen(int row); //放置皇后bool Judgement();//判断是否符合条件void Print();//输出符合条件的皇后排列bool Empty(){if(top==-1) return true;else return false;}; //判断栈是否为空private:T data[StackSize]; //定义数组int top; //栈顶指针};template <class T>void SeqStack<T>::Push(T x) //入栈操作{if(top>=StackSize-1) throw"上溢";top++;//栈顶指针上移data[top]=x;}template <class T>void SeqStack<T>::Pop()//出栈操作{if(Empty()) throw"下溢";top--;//栈顶指针下移}template <class T>bool SeqStack<T>::Judgement()//判断该位置是否合适{for(int i=0;i<top;i++)if(data[top]==data[i]||(abs(data[top]-data[i]))==(top-i))//判断是否满足任意两个皇后不在同列同一斜线return false;return true;}template <class T>void SeqStack<T>::PlaceQueen(int row) //放置皇后{for (int i=0;i<StackSize;i++){Push(i); //入栈if (Judgement())//判断位置是否合适{if (row<StackSize-1)PlaceQueen(row+1); //如果合适满足条件则放置一个皇后,递归调用else{num++;//不满足条件则到下一行Print();//输出符合条件的皇后}}Pop();//出栈}}template <class T>void SeqStack<T>::Print()//输出皇后函数{cout<<"NO."<<num<<":"<<endl; for(int i=0;i<StackSize;i++){for(int j=0;j<data[i];j++){cout<<"□";}cout<<"■";for(int j=StackSize-1;j>data[i];j--){cout<<"□";}cout<<endl;}cout<<endl;}void main(){SeqStack<int> Queen;Queen.PlaceQueen(0);cout<<"总共有"<<num<<"种摆放方法。
数据结构上机实验报告
数据结构实验报告课程数据结构 _ 院系专业班级实验地点姓名学号实验时间指导老师数据结构上机实验报告1一﹑实验名称:实验一——链表二﹑实验目的:1.了解线性表的逻辑结构特性;2.熟悉链表的基本运算在顺序存储结构上的实现,熟练掌握链式存储结构的描述方法;3.掌握链表的基本操作(建表、插入、删除等)4. 掌握循环链表的概念,加深对链表的本质的理解。
5.掌握运用上机调试链表的基本方法三﹑实验内容:(1)创建一个链表(2)在链表中插入元素(3)在链表中删除一个元素(4)销毁链表四﹑实验步骤与程序#include <iostream.h>#include <malloc.h>typedef struct LNode{int data;struct LNode *next;}Lnode, *LinkList;//假设下面的链表均为带头结点。
void CreatLinkList(LinkList &L,int j){//建立一个链表L,数据为整数,数据由键盘随机输入。
LinkList p,q;L=(LinkList )malloc(sizeof(Lnode));L->next=NULL;q=L;cout<<"请输入一个链表:"<<endl;for(int i=0;i<j;i++){ p=(LinkList)malloc(sizeof(Lnode));cin>>p->data;p->next=q->next;q->next=p;q=p;}}int PrintLinkList(LinkList &L){//输出链表L的数据元素LinkList p;p=L->next;if(L->next==NULL){cout<<"链表没有元素!"<<endl;return 0;}cout<<"链表的数据元素为:";while(p){cout<<p->data<<" ";p=p->next;}cout<<endl;return 1;}void LinkListLengh(LinkList &L){//计算链表L的数据元素个数。
数据结构实验报告二(栈、队列与杨辉三角)
《数据结构》实验报告项目名称栈、队列与杨辉三角专业班级软件工程工科试验班学号3903120128姓名谢江实验成绩:批阅教师:2012年5月22 日实验1《单链表的建立与约瑟夫问题》实验学时:实验地点:寝室与实验室实验日期:2012年5月22日1.需求分析实验2 主要是关于栈。
队列的建立以及杨辉三角问题的解决(队列运用)2.概要设计以及详细设计(1)栈class Stack{public:Stack();bool empty();//判断栈是否为空T peek();//显示栈顶元素void push(T value);//入栈T pop();//出栈int getSize();//当前栈中元素的数量private:T *elements;//数组指针int size;//栈中的元素数量int capacity;//栈的容量void ensureCapacity();//确认栈的容量是否大于元素数量};(2)队列class Queue{public:Queue();void enQueue(T element);//元素入队T deQueue();//元素出对,如果没有元素,抛出异常int getSize();//获取队列大小private:LinkedList<T> list;//定义表};3.调试分析内容包括:调试过程中遇到的问题是如何解决的以及对设计与实现的回顾讨论和分析;算法的时空分析(包括基本操作和其他算法的时间复杂度和空间复杂度的分析)和改进设想;经验和体会等。
个人标记:能建立顺序栈,以及链表顺序队列,对于比较复杂的链栈、循环队列等比较不熟悉,杨辉三角问题存在问题此次报告暂时不交,还有就是抛出异常的问题,例如:T deQueue()throw (runtime_error);//元素出对,如果没有元素,抛出异常会提示警告:C++ exception specification ignored except to indicate a function is not_declspec(nothrow)于是尽可能用if(…)throw runtime_error,就不报错了4.附录(1)栈Stack.h*****************************//采用数组的方式进行栈的操作#ifndef STACK_H#define STACK_Htemplate<typename T>class Stack{public:Stack();bool empty();//判断栈是否为空T peek();//显示栈顶元素void push(T value);//入栈T pop();//出栈int getSize();//当前栈中元素的数量private:T *elements;//数组指针int size;//栈中的元素数量int capacity;//栈的容量void ensureCapacity();//确认栈的容量是否大于元素数量};template<typename T>Stack<T>::Stack(){capacity = 10;//初始栈的大小size = 0;//初始元素的数量elements = new T[capacity];//建立指针}template<typename T>bool Stack<T>::empty(){if(size == 0)return true;elsereturn false;}template<typename T>//只显示栈顶元素并不出栈T Stack<T>::peek(){return elements[size - 1];}template<typename T>void Stack<T>::ensureCapacity(){if(size >= capacity)//如果满足进行指针的更换{T *old = elements;capacity = size + 1;elements = new T[capacity];for(int i = 0; i < size; i++)elements[i] = old[i];delete old;}}template<typename T>void Stack<T>::push(T value){ensureCapacity();//入栈前进行栈是否溢出的判断elements[size++] = value;}template<typename T>T Stack<T>::pop(){return elements[--size];}template<typename T>int Stack<T>::getSize(){return size;}#endif*************************************TestStack.cpp*************************************#include<iostream>#include"Stack.h"using namespace std;int main(){Stack<int> intS;cout << "before push size of intStack is: " << intS.getSize() << endl;//统计入栈前栈的大小for(int i = 0; i < 10; i++){int num;cout << "enter num: ";cin >> num;intS.push(num);}cout << "now size of intStack is: " << intS.getSize() << endl;//统计入栈后栈的大小while(!intS.empty()){cout << intS.pop() << " out " << endl;}cout << "after pop size of intStack is: " << intS.getSize() << endl;//出站后栈的大小system("pause");return 0;}##################################################(2)队列LinkedList.h******************************************#ifndef LINKEDLIST_H#define LINKEDLIST_H#include<stdexcept>using namespace std;template<typename T>class Queue;//前视定义,否则无法友元template<typename T>class Node{public :T element;//节点数据域Node<T> *next;//指向下指针Node(){next = NULL;}Node(T element){this -> element = element;next = NULL;}};template<typename T>class LinkedList{public:LinkedList();T removeFirst();//移除并返回表头元素void addLast(T element);//尾端插入新元素int getSize();//获取表的大小private:Node<T> *head, *tail;//定义头节点、尾节点int size;};template<typename T>LinkedList<T>::LinkedList()//初始化链表NULL{head = tail = NULL;size = 0;}template<typename T>void LinkedList<T>::addLast(T element){if(tail == NULL){head = tail = new Node<T>(element);}else{tail ->next = new Node<T>(element);tail = tail ->next;}size++;//作添加工作,size++}template<typename T>T LinkedList<T>::removeFirst(){if(size == 0)throw runtime_error("No elements");//抛出异常情况else{//删除并返回头节点元素,把下一节点作为新的头节点Node<T> *temp = head;head = head ->next;if(head == NULL)tail = NULL;size--;//作删除工作,size--T element = temp ->element;delete temp;return element;}}template<typename T>int LinkedList<T>::getSize()//返回size{return size;}#endif****************************************Queue.h***********************************#ifndef QUEUE_H#define QUEUE_H#include"LinkedList.h"#include<stdexcept>using namespace std;template<typename T>class Queue{public:Queue();void enQueue(T element);//元素入队T deQueue();//元素出对,如果没有元素,抛出异常int getSize();//获取队列大小private:LinkedList<T> list;//定义表};template<typename T>Queue<T>::Queue(){}//空的构造函数template<typename T>void Queue<T>::enQueue(T element){list.addLast(element);//入队(后插)}template<typename T>T Queue<T>::deQueue(){return list.removeFirst();//出对(前删)}template<typename T>int Queue<T>::getSize(){return list.getSize();}#endif******************************************* TestQueue.cpp*******************************************#include<iostream>#include<stdexcept>#include"Queue.h"using namespace std;int main(){Queue<int> q;cout << "before enQueue size is: " << q.getSize() << endl;for(int i = 0; i < 10; i++){q.enQueue(i);cout << i << " enter queue" << endl;}cout << "after enQueue size si: " << q.getSize() << endl;while(q.getSize()!=0){cout << q.deQueue() << "out queue" << endl;}cout << "after deQueue size is: " << q.getSize() << endl;system("pause");return 0;}。
北邮数据结构实验报告二_栈和队列
2009级数据结构实验报告实验名称:实验二栈和队列学生姓名:班级:班内序号:学号:日期:2010年12月18日实验要求题目四用栈做计算器。
设计一个算术四则运算表达式求值的简单计算器。
表达式求值是程序设计语言编译中最近本的问题,它要求把一个表达式翻译成能够直接求值的序列。
基本要求:输入中缀表达式能够转化成后缀表达式,比如输入中缀表达式“(A+B)*C”,输出“AB+C*”2、操作数使用单字母变量A、B、C等表示,操作符仅为+、-、*、/、(和);3、能够对变量A、B、C等赋值,得出正确的计算结果2. 程序分析首先,程序要求用户输入一个符号表达式,只能包含字母、+、-、*、/ 以及)和(,之后程序会用一个TurnInfixToPostfix()函数将表达式转化成后缀表达式存入一个栈中,转化过程借用逆波兰算法,建立一个符号栈,遍历用户输入的表达式,如果是字母,则直接输出,如果是运算符,则压入符号栈中(包括括号),在压栈的时候又需要注意,先要检查压栈前栈顶元素的优先级,如果优先级高于要压入的符号则直接压入该符号,否则要弹栈直到栈顶元素的优先级小于该元素的优先级然后才将该符号压入栈中(在压栈的时候会涉及到栈中有括号的情况,具体细节下面会说到),将转化的后缀表达式存入栈postfix,在输出的时候只要弹栈就行。
然后,要求用户逐个输入表达式中的字母的值,这时候,需要遍历当时在转化后缀表达式的时候过度容器vec_intoposfix,如果是字母则要求用户输入数值,压入用于计算的后缀表达式容器,如果是操作符则直接压入。
最后,在利用栈来计算值的时候,利用一个递归函数,就是一次弹栈,如果是操作符则先保存起来,接着继续弹栈,如果接下来的两个元素都为数字,就将这两个数字做相应的运算,然后压栈,如此反复,最后压入栈的元素就是表达式的值。
至此,程序的功能全部实现。
2.1 存储结构[内容要求]1、存储结构:顺序表、单链表或其他存储结构,需要画示意图,可参考书上P59页图2-92.2 关键算法分析关键算法一:将中缀表达式转化为后缀表达式VoidTurnInfixToPostfix(vector<char>&vec,stack<char>&sta,vector<char>&vecfix,stack< char>&stafix)1、 {2、int priority(-1);3、4、for (vector<char>::iterator itr=vec.begin();itr!=vec.end();itr++)5、{6、if(isLetter(*itr))7、{8、vecfix.push_back(*itr);9、}10、if (isOperator(*itr))11、{12、if(!sta.empty()) priority=getPriority(sta.top());13、else priority=-1;14、if (priority<getPriority(*itr)||priority==3&&sta.top()!=')')15、{16、sta.push(*itr);17、}18、else19、{20、if (sta.top()!=')')21、{22、while(priority>=getPriority(*itr)&&sta.top()!='(')23、{24、vecfix.push_back(sta.top());25、if (!sta.empty())26、{27、sta.pop();28、if(!sta.empty()) priority=getPriority(sta.top());29、else priority=-1;30、}31、else32、break;33、}34、sta.push(*itr);35、}36、else if(sta.top()==')')37、{38、while (sta.top()!='(')39、{40、vecfix.push_back(sta.top());41、if (!sta.empty()&&sta.top()!='(')42、{43、sta.pop();44、}45、else46、break;47、}48、}49、}50、51、52、}53、54、}55、for (vector<char>::iteratoritrfix=vecfix.end();itrfix!=vecfix.begin();--itrfix)56、stafix.push(*itrfix);57、stafix.push(*itrfix);58、}对表达式a + b * c – ( d – e) / f + g其符号栈的变化过程,红色表示未压栈的符号。
国家开放大学《数据结构》课程实验报告(实验2——线性表)参考答案
//在链表中删除最高分和最低分结点
for(q=head,p=head->next;p!=NULL;q=p,p=p->next)
{
if(p==pmin) { q->next=p->next; p=q; } //删除最低分结点
};
typedef struct pw PW;
//定义链表结点
struct node
{
PW data;
struct node * next;
};
typedef struct node NODE;
NODE *create(int n); //建立单链表
void input(NODE *s,int i); //输入第i个评委信息
(5)遍历链表,累加求和,计算总分及平均分,并输出相关信息。
完整程序
//实验1.1线性表的链接存储结构
#include
#include
#include
#define PWRS 5 //定义评委人数
//定义评委信息
struct pw
{
char name[8]; //姓名
short age; //年龄
float score; //评分
NODE *create(int n)
{
NODE *head,*p,*q;
inti;
p=(NODE*)malloc(sizeof(NODE));
head=p; q=p; p->next=NULL;
for(i=1; i<=n; i++)
{
p=(NODE*)malloc(sizeof(NODE));
武汉理工数据结构实验2 栈和队列基本操作和应用
实验2 栈和队列的基本操作和应用1实验目的(1)熟练掌握顺序栈的基本操作。
(2)掌握顺序栈的应用。
(3)掌握顺序循环队列的基本操作。
(4)掌握链式队列的基本操作。
2实验内容(1)设计一个顺序栈的基本操作的演示程序;(2)利用顺序栈,进行整数的不同进制之间的转换;(3)设计一个顺序循环队列的基本操作演示程序;(4)设计一个链式队列的基本操作演示程序。
【基本要求】I.实验内容(1)的基本要求:编写一个程序,将一个顺序栈的元素依次取出,并打印其元素值。
II.实验内容(2)的基本要求:编写一个程序,将一个非负的十进制整数转换成二进制。
III.实验内容(3)的基本要求:编写一个程序,将一个顺序队列的元素依次取出,并打印其元素值。
IV.实验内容(4)的基本要求:编写一个程序,将一个链式队列的元素依次取出,并打印其元素值。
【测试数据】自定3实验结果按照学校实验格式要求撰写实验报告,内容主要包括1)实验目的;2)实验内容;3)实验环境和方法;4)实验过程描述;5)实验心得体会参考程序如下:实验内容(1)参考程序/*sqStack.h文件*/#define INIT_SIZE 100#define INCREMENT 10typedef int ElemType;//typedef char ElemType;typedef struct SqStack {ElemType *base;ElemType *top;int stacksize;}SqStack;enum Status{OK,ERROR,OVERFLOW};/*sqStackOp.h文件*/#include "sqStack.h"Status InitStack(SqStack &S) ;Status GetTop(SqStack S,ElemType &e);Status Push(SqStack &S,ElemType e);Status Pop(SqStack &S,ElemType &e);bool StackEmpty(SqStack &S);/*sqStackOp.cpp文件*/#include <malloc.h>#include <stdlib.h>#include "sqStackOp.h"Status InitStack(SqStack &S) {//构造一个空的栈S.base=(ElemType*)malloc(INIT_SIZE*sizeof(ElemType));if(! S.base) exit(OVERFLOW); //存储分配失败S.top=S.base;S.stacksize=INIT_SIZE;return OK;} //InitStackStatus GetTop(SqStack S,ElemType &e){//若栈不空,则用e返回S的栈顶元素,并返回OK;否则返回ERROR if(S.top==S.base) return ERROR;e=*(S.top-1);return OK;} //GetTopStatus Push(SqStack &S,ElemType e){//插入元素e为新的栈顶元素if(S.top-S.base>=S.stacksize){ //栈满,追加存储空间S.base=(ElemType *)realloc(S.base,(S.stacksize+INCREMENT)*sizeof(ElemType));if(!S.base)exit(OVERFLOW); //存储分配失败S.top=S.base+S.stacksize;S.stacksize+=INCREMENT;}*S.top++=e;return OK;} //PushStatus Pop(SqStack &S,ElemType &e){//若栈不空,则删除S的栈顶元素,用e返回其值,并返回OK;否则返回ERRORif(S.top==S.base) return ERROR;e=*(--S.top);return OK;} //Push//判断栈是否为空bool StackEmpty(SqStack &S){if(S.top == S.base)return true;elsereturn false;}/*main.cpp文件*/#include <stdio.h>#include <stdlib.h>#include "sqStackOp.h"void main(){printf("Hellow stack \n");SqStack S; //定义顺序栈Sif(OK != InitStack(S)) {printf("顺序栈初始化出错,退出....\n");exit(-1);}Push(S, 1);Push(S,2);Push(S,3);int e;Pop(S, e);printf("出栈元素= %d \n",e);Push(S,4);Push(S,5);while(!StackEmpty(S)){Pop(S, e);printf("出栈元素= %d \n",e);}/*SqStack S; char x,y;InitStack(S); x='c';y='k';Push(S,x); Push(S,'a'); Push(S,y);Pop(S,x); Push(S,'t'); Push(S,x);Pop(S,x); Push(S,'s');while(!StackEmpty(S)){ Pop(S,y);printf("%c ",y); };printf("%c ",x);*/getchar();}实验内容(2)参考程序/*sqStack.h文件*/#define INIT_SIZE 100#define INCREMENT 10typedef int ElemType;typedef struct SqStack {ElemType *base;ElemType *top;int stacksize;}SqStack;enum Status{OK,ERROR,OVERFLOW};/*sqStackOp.h文件*/#include "sqStack.h"Status InitStack(SqStack &S) ;Status GetTop(SqStack S,ElemType &e);Status Push(SqStack &S,ElemType e);Status Pop(SqStack &S,ElemType &e);bool StackEmpty(SqStack &S);/*sqStackOp.cpp文件*/#include <malloc.h>#include <stdlib.h>#include "sqStackOp.h"Status InitStack(SqStack &S) {//构造一个空的栈S.base=(ElemType*)malloc(INIT_SIZE*sizeof(ElemType));if(! S.base) exit(OVERFLOW); //存储分配失败S.top=S.base;S.stacksize=INIT_SIZE;return OK;} //InitStackStatus GetTop(SqStack S,ElemType &e){//若栈不空,则用e返回S的栈顶元素,并返回OK;否则返回ERRORif(S.top==S.base) return ERROR;e=*(S.top-1);return OK;} //GetTopStatus Push(SqStack &S,ElemType e){//插入元素e为新的栈顶元素if(S.top-S.base>=S.stacksize){ //栈满,追加存储空间S.base=(ElemType *)realloc(S.base,(S.stacksize+INCREMENT)*sizeof(ElemType));if(!S.base)exit(OVERFLOW); //存储分配失败S.top=S.base+S.stacksize;S.stacksize+=INCREMENT;}*S.top++=e;return OK;} //PushStatus Pop(SqStack &S,ElemType &e){//若栈不空,则删除S的栈顶元素,用e返回其值,并返回OK;否则返回ERRORif(S.top==S.base) return ERROR;e=*(--S.top);return OK;} //Push//判断栈是否为空bool StackEmpty(SqStack &S){if(S.top == S.base)return true;elsereturn false;}/*main.cpp文件*/#include <stdio.h>#include <stdlib.h>#include "sqStackOp.h"void main(){SqStack s;int x;InitStack(s);scanf("%d",&x); //%d--十进制输入;%O--八进制输入;%x--十六进制输入//修改这里输入进制和下面整除和余数计算,就可以获得其他进制的转换while(x!=0){Push(s,x%8);x=x/8;}while(!StackEmpty(s)){Pop(s,x);printf("%d ",x);}printf("\n");getchar();}实验内容(3)参考程序/*sqQueue.h 文件*/#define MAXQSIZE 100typedef int QElemType;typedef struct SqQueue {QElemType *base;int front;int rear;}SqQueue;enum Status{OK,ERROR,OVERFLOW};/*sqQueueOp.h 文件*/#include "sqQueue.h"Status InitQueue (SqQueue &Q) ;Status EnQueue (SqQueue &Q, QElemType e);Status DeQueue (SqQueue &Q, QElemType &e) ;bool QueueEmpty(SqQueue &Q);int QueueLength(SqQueue Q);/*sqQueueOp.cpp 文件*/#include <malloc.h>#include <stdlib.h>#include "sqQueueOp.h"Status InitQueue (SqQueue &Q) {// 构造一个空队列QQ.base = (QElemType *) malloc(MAXQSIZE *sizeof (QElemType));if (!Q.base) exit (OVERFLOW);// 存储分配失败Q.front = Q.rear = 0;return OK;}Status EnQueue (SqQueue &Q, QElemType e) { // 插入元素e为Q的新的队尾元素if ((Q.rear+1) % MAXQSIZE == Q.front)return ERROR; //队列满Q.base[Q.rear] = e;Q.rear = (Q.rear+1) % MAXQSIZE;return OK;}Status DeQueue (SqQueue &Q, QElemType &e) { // 若队列不空,则删除Q的队头元素,// 用e返回其值,并返回OK; 否则返回ERRORif (Q.front == Q.rear) return ERROR;e = Q.base[Q.front];Q.front = (Q.front+1) % MAXQSIZE;return OK;}//判断队列是否为空bool QueueEmpty(SqQueue &Q){if(Q.front== Q.rear)return true;elsereturn false;}//计算循环队列长度int QueueLength(SqQueue Q){return (Q.rear - Q.front + MAXQSIZE) % MAXQSIZE;}/*main.cpp 文件*/#include <stdio.h>#include <stdlib.h>#include "sqQueueOp.h"void main(){printf("Hello Queue \n");SqQueue Q; //定义顺序队列QQElemType e;if(OK != InitQueue(Q)) {printf("顺序队列初始化出错,退出....\n");exit(-1);}EnQueue(Q,1);EnQueue(Q,3);EnQueue(Q,5);EnQueue(Q,7);printf("当前队列长度= %d \n",QueueLength(Q));DeQueue(Q,e);printf("队首元素%d出队,当前队列长度=%d\n",e,QueueLength(Q));EnQueue(Q,9);EnQueue(Q,11);while(!QueueEmpty(Q)){DeQueue(Q,e);printf("队首元素%d出队,当前队列长度=%d\n",e,QueueLength(Q));}getchar();}实验内容(4)参考程序/*linkQueue.h 文件*/typedef int QElemType;typedef struct QNode {// 结点类型QElemType data;struct QNode *next;} QNode, *QueuePtr;typedef struct { // 链队列类型QueuePtr front; // 队头指针QueuePtr rear; // 队尾指针} LinkQueue;enum Status{OK,ERROR,OVERFLOW};/*linkQueueOp.h 文件*/#include "linkQueue.h"Status InitQueue (LinkQueue &Q) ;Status EnQueue (LinkQueue &Q, QElemType e); Status DeQueue (LinkQueue &Q, QElemType &e) ; bool QueueEmpty(LinkQueue &Q);/*linkQueueOp.cpp 文件*/#include <malloc.h>#include <stdlib.h>#include "linkQueueOp.h"Status InitQueue (LinkQueue &Q) {// 构造一个空队列QQ.front = Q.rear = (QueuePtr)malloc(sizeof(QNode));if (!Q.front) exit (OVERFLOW);//存储分配失败Q.front->next = NULL;return OK;}Status EnQueue (LinkQueue &Q, QElemType e) { // 插入元素e为Q的新的队尾元素QueuePtr p = (QueuePtr) malloc (sizeof (QNode));if (!p) exit (OVERFLOW); //存储分配失败p->data = e;p->next = NULL;Q.rear->next = p;Q.rear = p;return OK;}Status DeQueue (LinkQueue &Q, QElemType &e) { // 若队列不空,则删除Q的队头元素,//用e 返回其值,并返回OK;否则返回ERROR if (Q.front == Q.rear) return ERROR;QueuePtr p = Q.front->next;e = p->data;Q.front->next = p->next;if (Q.rear == p) Q.rear = Q.front;free (p);return OK;}//判断队列是否为空bool QueueEmpty(LinkQueue &Q){if(Q.front == Q.rear)return true;elsereturn false;}/*main.cpp 文件*/#include <stdio.h>#include <stdlib.h>#include "linkQueueOp.h"void main(){printf("Hello LinkQueue \n");LinkQueue Q; //定义顺序队列QQElemType e;if(OK != InitQueue(Q)) {printf("顺序队列初始化出错,退出....\n");exit(-1);}EnQueue(Q,1);EnQueue(Q,3);EnQueue(Q,5);EnQueue(Q,7);DeQueue(Q,e);printf("队首元素%d出队,\n",e);EnQueue(Q,9);EnQueue(Q,11);while(!QueueEmpty(Q)){DeQueue(Q,e);printf("队首元素%d出队,\n",e);}getchar();}。
使用数据结构基础第五版王中华课后实验
使用数据结构基础第五版王中华课后实验
本次实验是基于《数据结构基础》第五版王中华教授所编写的课本,实验内容包含了
课后习题的部分,并且结合课本中的数据结构实现,加以实践与验证。
实验一:线性表的基本操作
1、目的:加深对线性表基本概念的理解与掌握。
掌握线性表的初始化,清空,判空,获取长度等基本操作。
2、实验步骤:
(1)根据课本提供的线性表结构体定义,编写相应的初始化函数。
(2)编写线性表的清空、判空、获取长度等基本操作函数。
(3)测试以上函数是否正确。
3、实验结果:
测试函数结果均正确。
加深了对线性表基本操作的理解。
实验二:顺序表的插入与删除
1、目的:了解顺序表的插入和删除的实现过程,掌握插入和删除的操作方式和效
果。
(2)实现顺序表的插入(在指定位置插入)和删除(删除指定位置元素)操作。
测试函数结果正确。
了解了单链表和双链表的实现过程,掌握了链表的插入和删除操
作方法。
1、目的:了解栈的基本概念和操作方法,掌握栈的初始化、入栈、出栈、获取栈顶
元素、栈空及栈长等基本操作方法。
(2)实现队列的初始化、入队、出队、获取队头元素、队空及队长等基本操作方法。
总结:通过对《数据结构基础》第五版王中华教授所编写的课本进行实验,加深了对
线性表、顺序表、链表、栈和队列的理解,掌握了这些数据结构的基本操作方法和实现原理。
本次实验让我更有信心在数据结构的学习与实践中取得更好的结果。
数据结构 实验二:单链表的基本操作
数据结构实验二:单链表的基本操作数据结构实验二:单链表的基本操作实验二:单链表的基本操作一、【实验目的】1、理解和掌握单链表的类型定义方法和结点生成方法。
2、掌握建立单链表和显示单链表元素的算法。
3、掌握单链表的查找、插入和删除算法二、【实验内容】1、建立一个整形数的单链表,手动输入10个数,并从屏幕显示单链表元素列表。
2、从键盘输入一个数,查找在以上创建的单链表中是否存在该数;如果存在,显示它的位置;如果不存在,给出相应提示。
3、删除上述单链表中指定位置的元素。
以下就是程序部分代码,恳请调试并补足并使之恰当运转:1.linlist.htypedefstructnode{datatypedata;structnode*next;}slnode;voidlistinitiate(slnode**head)/*初始化*/{/*如果有内存空间,申请头结点空间并使头指针head指向头结点*/if((*head=(slnode*)malloc(sizeof(slnode)))==null)exit(1);(*head)->next=null;/*置链尾标记null*/}intlistlength(slnode*head){slnode*p=head;/*p指向首元结点*/intsize=0;/*size初始为0*/while(p->next!=null)/*循环计数*/{p=p->next;size++;}returnsize;}intlistinsert(slnode*head,inti,datatypex)/*在带头结点的单链表head的数据元素ai(0≤i≤size)结点前*//*填入一个存放数据元素x的结点*/{slnode*p,*q;intj;p=head;/*p指向首元结点*/j=-1;/*j起始为-1*/while(p->next!=null&&j<i-1)/*最终让指针p指向数据元素ai-1结点*/{p=p->next;j++;}if(j!=i-1){printf(\填入边线参数弄错!\return0;}/*生成新结点由指针q指示*/if((q=(slnode*)malloc(sizeof(slnode)))==null)exit(1);q->data=x;q->next=p->next;/*给指针q->next赋值*/p->next=q;/*给指针p->next重新赋值*/return1;}intlistdelete(slnode*head,inti,datatype*x)/*删除带头结点的单链表head的数据元素ai(0≤i≤size-1)结点*//*删除结点的数据元素域值由x带回。
《数据结构》实验书
目录实验一线性表基本操作的编程实现 (201)实验二堆栈或队列基本操作的编程实现 (49)实验四二维数组基本操作的编程实现 (18)实验五二叉树基操作的编程实现 (20)实验六图基本操作的编程实现 (45)(特别提示:程序设计包含两个方面的错误。
其一是错误,其二是能错误。
为了提高学生的编程和能力,本指导书给出的程序代码并的两种错误。
并且也不保证程序的完整性,有一些语句已经故意删除,就是要求学生自己编制完成,这样才能达到我们的要求。
希望大家以自己所学高级语言的基本功和点为基础,不要过于依赖给出的参考代码,这样才能有所进步。
如果学生能够根据要求完全自己编制,那就不好了。
)实验一线性表基本操作的编程实现【实验目的】线性表基本操作的编程实现要求:线性表基本操作的编程实现(2学时,验证型),掌握线性表的建立、遍历、插入、删除等基本操作的编程实现,也可以进一步编程实现查找、逆序、排序等操作,存储结构可以在顺序结构或链表结分主要功能,也可以用菜单进行管理完成大部分功能。
还鼓励学生利用基本操作进行一些更实际的应用型程序设计。
【实验性质】【实验内容】把线性表的顺序存储和链表存储的数据插入、删除运算其中某项进行程序实现。
建议实现键盘输入数据以实现程序的通据的函数。
【注意事项】【思考问题】1.线性表的顺序存储和链表存储的差异?优缺点分析?2.那些操作引发了数据的移动?3.算法的时间效率是如何体现的?4.链表的指针是如何后移的?如何加强程序的健壮性?【参考代码】(一)利用顺序表完成一个班级学生课程成绩的简单管理1、预定义以及顺序表结构类型的定义(1)#define ListSize //根据需要自己设定一个班级能够容纳的最大学生数(2)typedef struct Stu{int num; //学生的学号char name[10]; //学生的姓名float wuli; //物理成绩float shuxue; //数学成绩float yingyu; //英语成绩}STUDENT; //存放单个学生信息的结构体类型typedef struct List{stu[ListSize]; //存放学生的数组定义,静态分配空间int length; //记录班级实际学生个数}LIST; //存放班级学生信息的顺序表类型2、建立班级的学生信息void listcreate(LIST *Li,int m) //m为该班级的实际人数{int i;Li->length=0;for(i=0;i<m;i++) //输入m个学生的所有信息{printf("please input the %dth student's information:\n",i+1);printf("num=");scanf("%d", ); //输入第i个学生的学号printf("name=");scanf("%s", ); //输入第i个学生的姓名printf("wuli=");scanf("%f", ); //输入第i个学生的物理成绩printf("shuxue=");scanf("%f", ); //输入第i个学生的数学成绩printf("yingyu=");scanf("%f", ); //输入第i个学生的英语成绩Li->length++; //学生人数加1}}3、插入一个学生信息int listinsert(LIST *Li,int i) //将学生插入到班级Li的第i个位置。
数据结构实验二 线性表
数据结构实验二线性表数据结构实验二线性表1. 实验目的1.1 理解线性表的概念和特性1.2 学习线性表的顺序存储结构和链式存储结构1.3 掌握线性表的基本操作:初始化、插入、删除、查找、修改、遍历等1.4 熟悉线性表的应用场景2. 实验内容2.1 线性表的顺序存储结构实现2.1.1 定义线性表结构体2.1.2 初始化线性表2.1.3 插入元素2.1.4 删除元素2.1.5 查找元素2.1.6 修改元素2.1.7 遍历线性表2.2 线性表的链式存储结构实现2.2.1 定义链表节点结构体2.2.2 初始化链表2.2.3 插入元素2.2.4 删除元素2.2.5 查找元素2.2.6 修改元素2.2.7 遍历链表3. 实验步骤3.1 实现顺序存储结构的线性表3.2 实现链式存储结构的线性表3.3 编写测试程序,验证线性表的各种操作是否正确3.4 进行性能测试,比较两种存储结构的效率差异4. 实验结果与分析4.1 执行测试程序,检查线性表的操作结果是否正确4.2 对比顺序存储结构和链式存储结构的性能差异4.3 分析线性表的应用场景,总结线性表的优缺点5. 实验总结5.1 总结线性表的定义和基本操作5.2 回顾实验中遇到的问题和解决方法5.3 提出对线性表实现的改进方向和思考附件:请参考附件中的源代码和实验报告模板。
法律名词及注释:1. 版权:指对某一作品享有的法律上的权利,包括复制权、发行权、改编权等。
2. 法律责任:指违反法律或合同规定所承担的责任。
3. 保密义务:指个人或组织根据法律、法规、合同等规定需要承担的保密责任。
4.知识产权:指人们在社会实践中所创造的智力劳动成果所享有的权利,包括专利权、著作权、商标权等。
数据结构实验报告(二)栈的应用
数据结构实验报告(⼆)栈的应⽤实验说明数据结构实验⼆ 栈的实验——栈的简单应⽤⼀、实验⽬的通过本实验使学⽣了解栈的简单应⽤,熟悉栈的特性及栈在顺序存储上的操作特点,深刻理解栈的基本操作与⽤栈解决应⽤问题的关系;特别训练学⽣使⽤栈解决实际问题的能⼒,为今后⽤栈解决相关问题奠定基础。
⼆、实验内容1.编程实现对给定的⼀组括号序列判断其是否匹配正确。
要求:(1)它必须成对出现,如“(”“)”是⼀对,“[”与“]”是⼀对;(2)出现时有严格的左右关系;(3)可以以嵌套的⽅式同时出现多组多括号,但必须是包含式嵌套,不允许交叉式嵌套。
⽐如“( )”、“[([][])]”这样是正确的,“[(])”或“([()))”或 “(()]”是不正确的。
(4)将处理的括号扩展为针对“()”“[]”“{}”三类。
2.编程实现⼀个简单的⾏编辑功能:⽤户可以输⼊⼀⾏内容,并可进⾏简易编辑。
要求:(1)遇到输⼊部分内容有误时操作退格符“#”表⽰前⼀位⽆效;(2)“@”表⽰之前的内容均⽆效。
实验报告1.实现功能描述编程实现对给定的⼀组括号序列判断其是否匹配正确,将处理的括号扩展为针对“()”“[]”“{}”三类,遇到输⼊部分内容有误时操作退格符“#”表⽰前⼀位⽆效;“@”表⽰之前的内容均⽆效。
2.⽅案⽐较与选择(1)可以使⽤栈和队列来实现。
因为栈的功能⾜以完成题⽬要求,所以初步打算使⽤栈来实现。
(2)因为编写⼀个标准的栈⽐较繁琐,⽽且本题中也没有⽤到所有栈的标准操作,所以通过模拟栈来完成本题。
(3)可以使⽤数组或链表来模拟栈。
因为括号匹配只有3对,所需空间不是很⼤,⼜因为特殊操作#、@可以在数组中通过-1和赋0值实现,因此选择了数组法来模拟栈。
3.设计算法描述(1)定义3个变量,分别⽤于记录()、[]、{}的出现次数。
遇到左符号时变量++,遇到右符号时--,变量为0时表⽰空栈。
当读到#时,再往前读⼀个字符,如果是()、[]、{}中的⼀种,则对其进⾏反向运算,即遇到右符号时++,遇到左符号时--。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
《数据结构》实验报告二学校:班级:学号:姓名:日期:程序名:一、上机实验的问题和要求:单链表的查找、插入与删除。
设计算法,实现线性结构上的单链表的产生以及元素的查找、插入与删除。
具体实现要求:1.从键盘输入20个整数,产生不带表头的单链表,并输入结点值。
2.从键盘输入1个整数,在单链表中查找该结点的位置。
若找到,则显示“找到了”;否则,则显示“找不到”。
3.从键盘输入2个整数,一个表示欲插入的位置i,另一个表示欲插入的数值x,将x插入在对应位置上,输出单链表所有结点值,观察输出结果。
4.从键盘输入1个整数,表示欲删除结点的位置,输出单链表所有结点值,观察输出结果。
5.将单链表中值重复的结点删除,使所得的结果表中个结点值均不相同,输出单链表所有结点值,观察输出结果。
6.删除其中所有数据值为偶数的结点,输出单链表所有结点值,观察输出结果。
7.把单链表变成带表头结点的循环链表,输出循环单链表所有结点值,观察输出结果。
8.(★)将单链表分解成两个单链表A和B,使A链表中含有原链表中序号为奇数的元素,而B链表中含有原链表中序号为偶数的元素,且保持原来的相对顺序,分别输出单链表A和单链表B的所有结点值,观察输出结果。
二、程序设计的基本思想,原理和算法描述:(包括程序的结构,数据结构,输入/输出设计,符号名说明等)这是一个带头结点的线性链表,数据域存放整形数据,由用户输入。
头结点数据域存链表长度,所以程序中有个求链表长度的函数int LengthList(LinkList L); //求链表长度L是指向头结点的指针,将长度值存入语句为L->data = LengthList(L);为了实时观察链表情况,程序中有个输出链表数据的函数void PrintList(LinkList L); //输出链表程序可以实现8种不同的操作,这8种不同的操作由8个函数实现,分别是void CreateList(LinkList &L); //创建链表void Locate(LinkList L); //查询数值void InsertList(LinkList &L); //插入数值void DeleteList(LinkList &L); //选择删除void Deleterepeat(LinkList &L); //删除重复结点void DeleteEven(LinkList &L); //删除数值为偶数的结点void Rotate(LinkList &L); //变为循环链表void Divide(LinkList &L); //分解成两个链表这些基本操作的实现算法都比较简单,有些跟书本上一样,有些需要自己稍作思考才能写出,具体程序见第三部分8种不同的操作可以由用户通过按A-H这八个字母键来选择,分别是A:创建B:查询C:插入D:选择删除E:删除重复F:删除偶数G:变为循环链表H:分解为两个链表,见第四部分输出截图,可以清晰的看到整个过程主程序中用开关语句实现:char operate;printf("\n\n输入字符选择链表操作类型\nA:创建B:查询C:插入D:选择删除E:删除重复F:删除偶数\nG:变为循环链表H:分解为两个链表\n");scanf("%c",&operate);switch (operate){case 'a':case 'A': CreateList(L);break;case 'b':case 'B': Locate(L);break;case 'c':case 'C': InsertList(L); break;case 'd':case 'D': DeleteList(L);break;case 'e':case 'E': Deleterepeat(L);break;case 'f':case 'F': DeleteEven(L);break;case 'g':case 'G': Rotate(L);break;case 'h':case 'H': Divide(L);break;case '\n':goto label;default: printf("输入有误,请重新输入!");break;}三、源程序及注释:#include<stdio.h>#include<malloc.h>typedef struct LNode //链表结点{int data;struct LNode *next;}LNode,*LinkList;int over_flag=0; //主函数结束标识符void CreateList(LinkList &L); //创建链表void Locate(LinkList L); //查询数值void InsertList(LinkList &L); //插入数值void DeleteList(LinkList &L); //选择删除void Deleterepeat(LinkList &L); //删除重复结点void DeleteEven(LinkList &L); //删除数值为偶数的结点void Rotate(LinkList &L); //变为循环链表void Divide(LinkList &L); //分解成两个链表int LengthList(LinkList L); //求链表长度void PrintList(LinkList L); //输出链表/********************************************************** ************主函数*********************************************************** ***********/void main(void){char operate;LinkList L;int n;for( n=0;n<40;n++){printf("\n\n输入字符选择链表操作类型\nA:创建B:查询C:插入D:选择删除E:删除重复F:删除偶数\nG:变为循环链表H:分解为两个链表\n");label:scanf("%c",&operate);switch (operate){case 'a':case 'A': CreateList(L);break;case 'b':case 'B': Locate(L);break;case 'c':case 'C': InsertList(L); break;case 'd':case 'D': DeleteList(L);break;case 'e':case 'E': Deleterepeat(L);break;case 'f':case 'F': DeleteEven(L);break;case 'g':case 'G': Rotate(L);break;case 'h':case 'H': Divide(L);break;case '\n':goto label; //排除换行键的影响default: printf("输入有误,请重新输入!");break;}if(over_flag)return;}}/********************************************************** ************创建链表*********************************************************** ***********/void CreateList(LinkList &L){int temp;printf("创建链表:\n请输入创建链表所需的整数值(以-1结束):");L = (LinkList)malloc(sizeof(LNode));L->next = NULL;LinkList q=L;scanf("%d",&temp);while(temp!=-1){LinkList p;p = (LinkList)malloc(sizeof(LNode));p->data = temp;p->next = NULL;q->next = p;q = q->next;scanf("%d",&temp);}L->data = LengthList(L);PrintList(L);}/********************************************************** ************查询元素*********************************************************** ***********/void Locate(LinkList L){ if(!L)printf("错误:链表未创建!");int element;printf("查询数值:\n输入要查询的数值:");scanf("%d",&element);LinkList p=L->next;int i =1;while(p){if(p->data==element){printf("找到了,它是链表的第%d个元素。
\n",i);return ;}p=p->next;i++;}printf("找不到。
\n");}/**********************************************************************插入数值*********************************************************** ***********/void InsertList(LinkList &L){int x,i;printf("插入数值:\n输入要插入的数值和插入的位置:");scanf("%d",&x);scanf("%d",&i);LinkList p = L;int j = 0;while (p && j < i-1){p = p->next;++j;}if (!p || j > i-1){printf("输入位置错误!") ;return;}LinkList s = (LinkList)malloc(sizeof(LNode));s->data = x;s->next = p->next;p->next = s;L->data = LengthList(L);PrintList(L);}/********************************************************** ************选择位置删除节点*********************************************************** ***********/void DeleteList(LinkList &L){int i;LinkList p = L;printf("选择位置删除结点:\n输入要删除数值的位置:");scanf("%d",&i);int j = 0;while (p->next && j < i-1){p = p->next;++j;}if (!(p->next) || j > i-1){printf("输入位置错误!") ;return;}LinkList q = p->next;p->next = q->next;free(q);L->data = LengthList(L);PrintList(L);}/********************************************************** ************删除重复结点*********************************************************** ***********/void Deleterepeat(LinkList &L){printf("删除重复结点后的链表为:\n");int n=1;int a[20];LinkList q=L->next; LinkList p=q->next;a[0]=q->data;while(p){for(int i=0;i<n;i++){if(p->data==a[i]){LinkList r=p;q->next=p->next;p=p->next;free(r);break;}}if(i==n){a[n++]=p->data;p=p->next;q=q->next;}}L->data = LengthList(L);PrintList(L);}/********************************************************** ************删除数值为偶数的结点*********************************************************** ***********/void DeleteEven(LinkList &L){printf("删除偶数结点后的链表为:\n");LinkList q=L;LinkList p=L->next;while(p){if(p->data%2==0){LinkList r=p;q->next=p->next;p=p->next;free(r);}else{p=p->next;q=q->next;}}L->data = LengthList(L);PrintList(L);}/********************************************************** ************变为循环链表*********************************************************** ***********/void Rotate(LinkList &L){printf("变为循环链表:\n");LinkList p=L;while(p->next)p=p->next;p->next=L;LinkList t=L->next;printf("长度:%d\t",L->data);printf("各个结点数值为:");while(t!=L){printf("%d\t",t->data);t=t->next;}printf("\n");printf("已经变为循环链表,其他操作将受影响,程序结束!\n");over_flag=1;}/********************************************************** ************分解成两个链表*********************************************************** ***********/void Divide(LinkList &L){printf("分解成两个链表:\n");LinkList A=L;LinkList B=(LinkList)malloc(sizeof(LNode)); B->next=NULL;LinkList Lb=B;int i=1;LinkList La=L;LinkList p=L->next;while(p){if(i++%2==0){La->next=p->next;p->next=NULL;Lb->next=p;Lb=Lb->next;p=La->next;}else{p=p->next;La=La->next;}}A->data = LengthList(A);printf("链表A:");PrintList(A);B->data = LengthList(B);printf("链表B:");PrintList(B);printf("已经分解成两个链表,其他操作将受影响,程序结束!\n");over_flag=1;}/********************************************************** ************求链表长度*********************************************************** ***********/int LengthList(LinkList L){int i=0;LinkList p=L->next;while(p){p=p->next;i++;}return i;}/********************************************************** ************输出链表*********************************************************** ***********/void PrintList(LinkList L){LinkList t=L->next;printf("长度:%d\t",L->data);printf("结点数值:");while(t){printf("%d\t",t->data);t=t->next;}printf("\n");}四、运行输出结果:五、调试和运行程序过程中产生的问题及采取的措施:1. 主程序中我用到char operate;scanf("%c",&operate);Operate存放用户选择操作类型的字母A-H,但是当用户键入字母后,要按ENTER 键表示输入完毕,所以以后执行scanf("%c",&operate);是会把ENTER输入到operate中,从而影响了后面的操作,解决方案是加一个标记位label :scanf("%c",&operate);当程序发现输入为ENTER时,回到labeL处,这样解决了问题。