数据结构上机报告(三)
数据结构上机操作实验报告

实验一单链表的基本操作(必做)一、实验目的1.掌握单链表的存储、初始化、插入、删除等操作的程序实现。
2.加深对单链表基本概念,基本理论及相应算法的掌握与理解。
3.了解链表的处理方式,学习体会简单的单链表程序实现相关知识。
二、实验内容1.建立一个链表、设计链表的基本操作实现算法、输出一个链表表,调试并输出结果。
2.编写一个程序实现如下功能:让计算机产生出50个0~9之间的随机数并依次保存到单链表中;输出遍历单链表;从单链表中删除与给定值相等的所有结点;输出遍历单链表;输出单链表长度,调试并输出结果。
三、实验步骤1.定义一个链表结构体。
2.利用插入功能插入一个结点。
3.利用删除功能删除一个结点。
四、程序运行测试1.利用插入功能插入一个结点。
2.利用删除功能删除一个结点。
五、实验报告要求1.绘制链表操作实现的流程图。
2.详细给出程序运行测试结果(包括测试数据和测试结果)。
3.选试验步骤2-3中的任意一个,给出程序的详细注释。
4.参考程序中某一部分功能的改进(选做)5.实验心得与体会6.附录,实验用源程序六、参考源代码#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的数据元素个数。
数据结构上机实验报告看病问题

数据结构上机实验报告题目:一个病人看病模拟程序学生姓名:周瑞楠学生学号:3013216085学院名称:计算机学院专业:计算机科学与技术时间:2014.10.28目录第一章,需求分析 (3)1.1 原题描述 (3)1.2 详细问题的解决方案 (3)1.2.1 解决方案要求 (3)1.2.2 各个环节功能要求 (4)第二章,概要设计 (5)2.1 抽象数据类型 (5)2.2 主要算法描述 (5)2.3 算法分析 (6)第三章,详细设计 (7)3.1 程序代码 (7)第四章,调试分析 (9)第五章,测试分析 (10)第六章,未来展望与思考 (11)第一章需求分析1.1 原题描述请按照如下要求编写一个病人看病模拟程序编写一个程序,反映病人到医院看病,排队看医生的情况。
在病人排队过程中,主要重复两件事:(1)病人到达诊室,将病历本交给护士,拍到等待队列中候诊。
(2)护士从等待队列中取出下一位病人的病例,该病人进入诊室就诊。
1.2详细问题的解决方案1.2.1问题分析要求模拟病人等待就诊这一过程,程序采用菜单方式,其选项及功能说明如下:(1)排队————输入排队病人的病历号,加入到病人排队队列中。
(2)就诊————病人排队队列中最前面的病人就诊,并将其从队列中删除。
(3)查看排队————从队首到队尾列出所有的排队病人的病历号。
(4)不再排队,余下依次就诊————从队首到队尾列出所有的排队病人的病历号,并退出运行。
(5)下班————退出运行。
1.2.2 解决方案要求测试数据及输出如下:1:排队 2:就诊 3:查看排队 4:不再排队,余下依次就诊 5:下班请选择:1 >>输入病历号:11:排队 2:就诊 3:查看排队 4:不再排队,余下依次就诊 5:下班请选择:1 >>输入病历号:21:排队 2:就诊 3:查看排队 4:不再排队,余下依次就诊 5:下班请选择:1 >>输入病历号:31:排队 2:就诊 3:查看排队 4:不再排队,余下依次就诊 5:下班请选择:2 >>病人1就诊1:排队 2:就诊 3:查看排队 4:不再排队,余下依次就诊 5:下班请选择:3 >>排队病人:2 31:排队 2:就诊 3:查看排队 4:不再排队,余下依次就诊 5:下班请选择:1 >>输入病历号:41:排队 2:就诊 3:查看排队 4:不再排队,余下依次就诊 5:下班请选择:4 >>病人按以下顺序就诊:2 3 41.2.3 各个环节功能要求表1-2.1 环节功能函数功能注意条件及限制规则initQueue()建立空队列头指针尾指针建立后判断是否为NULL EnQueue() 在队尾插入元素判断节点储存分配是否失败DeQueue() 删除对头元素并返回其值释放被删除的节点删除队尾元素注意改变指针位置ShowQueue() 输出队列元素补充正文:主函数里用switch来表明各种情况下应当调用的函数第二章概要设计2.1 抽象数据类型ADT deletenode{数据对象:D={ai|ai∈ElemSet,i=1,2,…,m, m≥0TermSet 中的每个元素包含一个整数}数据关系:R1={<a i,a i-1>| a i,a i-1∈D,且a i中的整数有序,i=2,3…,n} 约定其中a1端为队列投,an端为队列尾基本操作:InitQueue(&Q);操作结果:建立空队列。
数据结构与算法上机实验报告

数据结构与算法B上机实验报告第1次2011-10-02 顺序表的实现和基本操作第2次2011-10-29 二叉树的实现和递归遍历第3次2011-11-23 内部排序第4次2011-12-dd 实现图从邻接矩阵到邻接表存储转化第一次线性表数据结构一、上机实习题目线性链表操作——插入、删除、合并、排序、查找二数据结构设计(算法设计)源程序(#include <iostream>#define MaxSize 100using namespace std;typedef int ElemType;class SeqList{ElemType list[MaxSize];int length;public:SeqList() {length=0;}void SeqListSort(int i,ElemType x);void SeqListCreat(int n);void SeqListInset(int i,ElemType x);void SeqListDelete(int i);void SeqListMerge();int GetLength(){return length;}int SeqListFind(ElemType x);int SeqListIsEmpty();void SeqListPrint();}Mylist1,Mylist2;//创建顺序表void SeqList::SeqListCreat(int n){ElemType x;cout<<"请输入数据元素:";for (int i=0;i<n;i++){cin>>x;list[i]=x;length++;}}//对顺序表进行排序void SeqList::SeqListSort(int i,ElemType x) {for(int k=0;k<length;k++){for(i=k+1;i<=length;i++){if(list[k]>list[i]){x=list[k];list[k]=list[i];list[i]=x;}}}}//在顺序表L中的第i个位置插入新元素x void SeqList::SeqListInset(int i,ElemType x) {int k;if(length>=MaxSize)cout<<"表已满,无法插入!"<<endl;else if(i<0||i>length)cout<<"参数i不合理!"<<endl;else{for (k=length;k>=i;k--){list[k]=list[k-1];}list[i-1]=x;length++;}}//删除第i个位置的数据元素void SeqList::SeqListDelete(int i){int k;if(!SeqListIsEmpty())cout<<"表已空,无法删除!"<<endl;else if(i<0||i>length)cout<<"参数i不合理!"<<endl;elsefor(k=i-1;k<length;k++)list[k]=list[k+1];length--;}//查找元素x在表中的位置int SeqList::SeqListFind(ElemType x) {int i=0;while(i<length&&list[i]!=x)i++;if(i>length)return -1;elsereturn i+1;}//判断顺序表是否为空int SeqList::SeqListIsEmpty(){if(length<=0)return 0;else return 1;}//将顺序表显示在屏幕上void SeqList::SeqListPrint(){if(!SeqListIsEmpty())cout<<"空表!"<<endl;elsefor(int i=0;i<length;i++)cout<<list[i]<<" ";cout<<endl;}int main(){SeqList Mylist1,Mylist2;int i,n,flag=1,select;ElemType x;cout<<"1. 建立顺序表\n";cout<<"2. 对顺序表进行排序\n";cout<<"3. 求x数值的位置\n";cout<<"4. 在第i个位置插入新元素x\n"; cout<<"5. 删除第i个位置上的数值\n"; cout<<"6. 将两个顺序表合并\n";cout<<"7. 退出\n";cout<<endl;while (flag){cout<<"请选择操作:";cin>>select;switch(select){case 1:cout<<"请输入顺序表1的长度:";cin>>n;Mylist1.SeqListCreat(n);cout<<"你所输入的顺序表1为:";Mylist1.SeqListPrint();cout<<"请输入顺序表2的长度:";cin>>n;Mylist2.SeqListCreat(n);cout<<"你所输入的顺序表2为:";break;case 2:cout<<"请选择所要排序的顺序表1或2:"; cin>>n;if(n==1){Mylist1.SeqListSort(i,x);cout<<"排序后的顺序表1为:";Mylist1.SeqListPrint();}else{Mylist2.SeqListSort(i,x);cout<<"排序后的顺序表2为:";Mylist2.SeqListPrint();}break;case 3:cout<<"请输入x的值:";cin>>x;i=Mylist1.SeqListFind(x);if(i!=-1) cout<<"x的位置为:"<<i<<endl;else cout<<"没有找到!";break;case 4:cout<<"请输入要插入的元素的位置和数值x:"; cin>>i>>x;cout<<"插入后的顺序表为:";Mylist1.SeqListPrint();break;case 5:cout<<"请输入要删除的元素的位置:";cin>>i;Mylist1.SeqListDelete(i);cout<<"删除后的顺序表为:";Mylist1.SeqListPrint();break;case 6:cout<<"合并后的顺序表为:\n";Mylist1.SeqListPrint();Mylist2.SeqListPrint();break;case 7:flag=0;break;}}}三运行结果为:四、上机环境和使用语言(计算机程序实现)Visual C++。
数据结构上机报告

数据结构上机报告班级:通信工程1405 姓名:李笑阳学号:U201413536一.约瑟夫环1.需求分析①.约瑟夫问题的一种描述是:编号为1,2,……,n点的n个人按顺时针方向围坐一个圈,每人持有一个密码。
一开始选一个正整数作为报数上限值m,从第一个人开始从顺时针方向自1开始报数,报到m时停止。
报到m的人出列,将他的密码作为新的m值,从他在顺时针方向上的下一个人开始从新从1报数,如此下去,直达所有人出列。
②.基本要求:利用单向循环链表存储结构模拟此过程,按照出列的顺序输出各人的编号。
③.演示程序提示用户输入其总人数,然后依此输入每个人的数字,程序按照出列的顺序输出各人的编号。
测试数据:m的初始值为20;n=7,7个人的密码依次是3,1,7,2,4,8,4,首先m 的值为6(正确的出列顺序为6,1,4,7,2,3,5)2.设计概要①循环链表的结点类型定义typedef struct LNode②.创建链表模块LinkList creatList_L(int n)③.删除链表并释放空间模块void ListDelete_L(LinkList L,int key,int n)④.主函数模块(约瑟夫环的实现)Void main()3.具体代码实现#include<stdio.h>#include<malloc.h>//定义结构体typedef struct LNode{int password,num;struct LNode *next;}LNode,*LinkList;//创建链表LinkList creatList_L(int n){LinkList p,head,q;int i=1,key;head=(LinkList)malloc(sizeof(LNode));p=head;for(i=1;i<=n;i++) //进入循环赋值{scanf("%d",&key);q=p;p=(LinkList)malloc(sizeof(LNode));p->num=i;p->password=key;q->next=p;}p->next=head->next;free(head); ////现在的p节点是列表的尾节点把尾节点的下一个指向头结点//也就是形成了一个环head=p->next;return (head);}//输出并删除列表void ListDelete_L(LinkList L,int key,int n){LinkList p,s;int j=1;while(n>0){p=L;//key是人数上限M==key 现在开始循环叫数叫到M的输出//并从循环链表中删除for(j=1;j<key;j++){s=p;p=p->next;}printf("%2d %5d\n",p->num,p->password);key=p->password;//s是p的上一个节点,现在把s的下一个节点指向p的下一个s->next=p->next;L=p->next;//释放p节点free(p);//链表总数减一,一直到n==0时退出while循环n--;}}void main(){LinkList s;int n,m;printf("请输入总人数N和上限数M:");scanf("%d%d",&n,&m);printf("请输入%d个人的密码:",n);s=creatList_L(n); //调用创建列表printf("序号密码\n");ListDelete_L(s,m,n); //调用输出并删除列表}4.运行分析①.运行结果②.复杂度的分析时间复杂度为O(n2),空间复杂度为O(n)5.实验总结这个算法中的主函数只完成输入输出,其他都是通过调用完成。
数据结构上机报告 - 哈夫曼编码

数据结构上机报告题目:哈夫曼编/译码器一、需求分析1.问题描述问题描述:利用哈夫曼编码进行通信可以大大提高信道利用率,缩短信息传输时间,降低传输成本。
但是,这要求在发送端通过一个编码系统对待传数据预先编码,在接收端将传来的数据进行译码(解码)。
对于双工信道(即可以双向传输信息的信道),每端都需要一个完整的编/译码系统。
试为这样的信息收发站设计一个哈夫曼编译码系统。
2.基本要求一个完整的系统应具有以下功能:(1)I:初始化(Initialization)。
从终端读入字符集大小n,以及n个字符和n个权值,建立哈夫曼树,并将它存于文件hfmTree中。
(2)E:编码(Encoding)。
利用已建好的哈夫曼树(如不在内存,则从文件hfmTree 中读入),对文件ToBeTran中的正文进行编码,然后将结果存入文件CodeFile中。
(3)D:译码(Decoding)。
利用已建好的哈夫曼树将文件CodeFile中的代码进行译码,结果存入文件TextFile中。
(4)P:印代码文件(Print)。
将文件CodeFile以紧凑格式显示在终端上,每行50个代码。
同时将此字符形式的编码文件写入文件CodePrin中。
(5)T:印哈夫曼树(Tree printing)。
将已在内存中的哈夫曼树以直观的方式(树或凹入表形式)显示在终端上,同时将此字符形式的哈夫曼树写入文件TreePrint中。
3.预设需求(1)编码结果以文本方式存储在文件CodeFile中。
(2)用户界面可以设计为“菜单”方式:显示上述功能符号,再加上“Q”,表示退出运行Quit。
请用户键入一个选择功能符。
此功能执行完毕后再显示此菜单,直至某次用户选择了“Q”为止。
二、概要设计:程序用结构体数组类型存储哈夫曼树,先根据结点数初始化哈夫曼树,再进行哈夫曼树的构造及编码操作,并得出所需数据。
循环链表实现1、哈夫曼树的定义类型typedef struct { //Huffman树的定义char name;unsigned int w; //权值unsigned int pa; //父节点unsigned int lch; //左子树unsigned int rch; //右子树} HTnode;2、基本操作函数:void Reverse(char *str) { //字符串倒置,如此便不需要反向编码int i,j;char ch;for(i=0,j=strlen(str)-1; i<j; i++,j--) {ch=str[i];str[i]=str[j];str[j]=ch;}}int min_node(HTnode *HT,int n) { //寻找Node中最小的节点int i,min;for(i=1; HT[i].pa; i++); //寻找根节点min=i;for(i=1; i<n; i++)if(!HT[i].pa)if(HT[i].w<HT[min].w)min=i;HT[min].pa=1;return min;}3、主程序流程a.输入叶子节点个数和操作方式,并从DataFile.txt及ToBeTran.txt中读取数据。
数据结构上机实验

数据结构上机实验本课程实验中已知的预定义常量和类型如下:#define TRUE 1#define FALSE 0#define OK 1#define ERROR 0#define INFEASIBLE -1#define OVERFLOW -2typedef int Status;实验一顺序表(一)一、 实验目的掌握顺序表的定义、存储结构及其基本操作。
二、 实验内容已知:线性表的动态分配顺序存储结构为#define LIST_INIT_SIZE 100#define LISTINCREMENT 10typedef struct{int *elem;int length;int listsize;}SqList;在主程序中调用如下函数实现构造线性表,在线性表中插入数值,最后输出线性表。
1. 编写函数,Status InitList(SqList *L) 实现构造一个空的线性表,若构造成功则返回OK,否则返回ERROR。
2. 编写函数,Status ListInsert(SqList *L , int i , int e) 实现在线性表L中第i个位置之前插入新的数据元素e,L的长度加1。
若插入成功返回OK,否则返回ERROR。
(提示:i的合法值为:i>=1&&i<=L—>length+1)3. 编写函数,void ListPrint(SqList *L)实现将线性表中的元素依次输出到屏幕上。
4.编写函数,int Menu(),输出菜单项请选择你要进行的操作(请输入1-4中的任一个数字):输入1:InitList2:ListInsert3:ListPrint4:Exit实验二顺序表(二)一、 实验目的掌握顺序表的定义、存储结构及其基本操作。
二、 实验内容在实验一的基础上,继续完成如下实验内容。
1.编写函数,Status ListDelete(Splist *L ,int i ,int *e),实现删除L的第i个数据元素,并用e返回其值,L的长度减1。
数据结构上机实验_树和二叉树的应用_哈夫曼编码设计 (含代码和报告)
数据结构实验报告题目:数据结构实验报告学院:工商管理学院班级:信息1001姓名:彭振宇学号:时间:2012/6/26实验三:树和二叉树的应用一.实验题目:树和二叉树的应用二.实验内容:哈夫曼编码设计三.实验目的:掌握树和二叉树的概念及工作原理,运用其原理及概念完成上述实验题中的内容。
四.实验要求:为了使学生更好的掌握与理解课堂上老师所讲的概念与原理,实验前每个学生要认真预习所做的实验内容及编写源程序伪码(写在纸上及盘中均可)以便在实验课中完成老师所布置的实验内容。
五.概要设计原理:1.选择parent为0且weight最小的两个结点。
其序号分别为s1和s22.建立赫夫曼树叶3.从叶子到根逆向求每个字符的赫夫曼编码4.输出构造的树5.输出得到的各权Huffman编码六.详细程序清单及注释说明:#include<stdio.h>#include<stdlib.h>#include<string.h>#define MAXSIZE 30 //最大叶子数#define MAXCODE 10000 //编码最大长度#define OK 1#define ERROR 0#define OVERLOW -2//=============赫夫曼树和赫夫曼编码的存储表示=====typedef struct{unsigned int weight;unsigned int parent, lchild, rchild;}HTNode,*HuffmanTree; //动态分配数组存储赫夫曼树typedef char **HuffmanCode; //动态分配数组存储赫夫曼编码表/*----------------算法描述----------------*/void Select(HuffmanTree HT, int n, int *s1, int *s2)//选择parent为0且weight最小的两个结点。
数据结构栈和队列上机报告
数据结构栈和队列一上机的目的和要求实验目的:1.掌握实现栈/队列的基本操作方法2.掌握栈的基本操作:建栈,Push,Pop等运算在顺序存储上的实现3.掌握队列的基本操作:建队列,入队,出队等运算在顺序存储结构上的实现队列的实验参照栈编程实现。
实验报告要求:1. 上机前完成所有的函数编写2.实验记录部分填写编写主函数调用所写所有函数的屏幕输出3.实验总结部分填写对该次实验所编写函数的运行情况,和在实验过程中对栈的认识和实现情况二基本知识和原理栈和队列是两种常用的数据结构,栈和队列是操作受限的线性表,栈和队列的数据元素具有单一的前驱和后继的线性关系;栈和队列又是两种重要的抽象数据类型。
栈是限定在表尾进行插入和删除操作的线性表允许插入和删除的一端为栈顶,另一端为栈底,出栈元素只能是栈顶元素,后进先出,相邻元素具有前驱与后继关系。
队列是只允许在一端进行插入操作,在另一端进行删除操作的线性表。
允许插入的一端为队尾,允许删除的一端为队头,先进先出,相邻元素具有前驱与后继关系。
三程序算法分析及实现代码#include"stdio.h"#include"conio.h"#define MaxSize 100 /*栈中的元素的最大个数*/typedef int ElemType;typedef struct{ElemType data[MaxSize];/*存放堆栈的数组*/int top;/*栈顶元素*/}Stack,*S;/*堆栈的初始化*/void InitStack(Stack *S){/*指向的是最顶端的元素取值范围为从0~MaxSize-1为-1时说明为空栈*/S->top=-1;}int StackEmpty(SqStack *s) //判断是否为空{if(s->top==s->base){return TRUE;}else{return 0;}}int GetTop(SqStack* s,int *e) //取栈顶{//若栈不空,则用e返回S的栈顶元素,并返回OK;否则返回ERRORif(s->top==s->base){return ERROR;}*e=*(s->top-1);return 1;}int Push(SqStack *s,int e) //进栈{//插入元素e为新的栈顶元素if(s->top-s->base>=s->stacksize){//栈满,追加存储空间s->base=(int *)malloc(SIZE*sizeof(int));if(!s->base)exit(OVERFLOW);s->top=s->base + s->stacksize;s->stacksize +=SIZE;}*(s->top)++=e;return 1;}int Pop(SqStack *s ,int *e)//出栈{// 若栈不空,则删除S的栈顶元素,用e返回其值,并返回OK;否则返回ERRORif(s->base == s->top)return ERROR;*e = *--s->top;return 1;}int main ( ){SqStack sq;InitStack(&sq);int e;int N;int k;int n=0;Z:{printf("\n\t********************************************");printf("\n\t*** 请你输入相应的操作序号进行操作 ***");printf("\n\t*** 1.是否空 ***");printf("\n\t*** 2.取栈顶元素 ***");printf("\n\t*** 3.进栈 ***");printf("\n\t*** 4.出栈 ***");printf("\n\t*** 0. 退出 ***\n");printf("\t********************************************");printf("\n请选择功能:");scanf("%d",&k);switch(k){case 1:if(StackEmpty(&sq)){printf("该栈为空!");}else{printf("该栈非空!");}goto Z;break;case 2:GetTop(&sq, &e);printf("栈顶元素为:%d", e);goto Z;break;case 3:printf("请输入要进栈的元素:");scanf("%d", &e);Push(&sq, e);goto Z;break;case 4:Pop(&sq,&e);printf("%d", e);goto Z;break;case 0:exit(0);break;default:break;}}}二队列#include<iostream>#include<malloc.h>using namespace std;#define TRUE 1#define FLASE 0#define OK 1typedef struct QNode {char data;struct QNode *next;}QNode, *Queue;typedef struct {Queue front;Queue rear;}LinkQueue;void InitQueue(LinkQueue &Q)//创造空队{Q.front = Q.rear = (Queue)malloc(sizeof(QNode));if (!Q.front){printf("OVERFLOW" );}Q.front->next = NULL;// return OK;}void EnQueue(LinkQueue &Q, int e)//入队{Queue p = (Queue)malloc(sizeof(QNode));p->data = e;p->next = NULL;Q.rear->next = p;Q.rear = p;//return OK;}void DeQueue(LinkQueue &Q, int e)//出队{Queue p = (Queue)malloc(sizeof(QNode));if (Q.front == Q.rear){p rintf("队空");}p = Q.front->next;e = p->data;Q.front->next = p->next;if (Q.rear == p)Q.rear = Q.front;free(p);printf( " 元素已经出队");}int length(LinkQueue &Q)//求队列中元素个数{Queue p = (Queue)malloc(sizeof(QNode));p = Q.front->next;int i = 0;while (p != NULL){p = p->next;i++;}printf("队列中元素个数: ");printf(”%d”,i );return 1;}int QueueEmpty(LinkQueue &Q)//判队列空{if (Q.front == Q.rear)return TRUE;elsereturn FLASE;}int main(){LinkQueue Q;int k;Z:{printf(" \n\t********************************************");printf( "\n\t*** 请你输入相应的操作序号进行操作 ***");printf( "\n\t*** 1.初始化 ***");printf( "\n\t*** 2.入队 ***");printf( "\n\t*** 3.出队 ***");printf( "\n\t*** 4.求队列中元素个数 ***");printf( "\n\t*** 5.判队列是否为空 ***");printf( "\n\t********************************************");printf( "\n请选择功能:");cin >> k;switch (k){case 1:InitQueue(Q);goto Z;break;case 2:printf("请输入要插入的元素");int e;cin >> e;EnQueue(Q, e);goto Z;break;case 3:printf( "出队");int m;DeQueue(Q, m);goto Z;break;case 4:length(Q);goto Z;break;case 5:if (QueueEmpty(Q))printf("队列为空");elseprintf("队列不为空");goto Z;break;default:break;}}}四结果分析及测试相关记录队列入队求队列中元素个数出队列判断是否为空五实验体会和学习感悟学习完队列和栈一章后对其操作还有基本函数的运用有了基本的了解。
数据结构线性表上机报告
数据结构(Data Structure)上机报告学号********姓名********专业班级********时间********一上机的目的和要求1.掌握线性结构中顺序表和链表的基本概念、基本操作和应用;2.掌握线性表的基本操作:建表、插入、删除、输出等运算在顺序存储结构和链式存储结构上的实现。
3.通过本次实习加深对高级语言C语言的使用(特别是函数参数、指针类型、链表的使用)。
熟悉线性表的基本运算在两种存储结构(顺序结构和链式结构)上的实现。
二基本知识和原理(一)线性表是最常用的而且也是最简单的一种数据结构,简言之,一个线性表是N个数据元素的有限序列。
至于每个数据的具体含义,在不同的情况下各不相同,它可以是一个数或一个符号,也可以是一页书,甚至其他更复杂的信息。
例如26个英文元素的字母表(A,B,C,D,···),其数据结构的描述为:Linear_list=(D,R)其中,D={ ai |ai属于ElemSet,i=1,2,3,···},R={<ai-1,ai>| i=2,3,4,…… }。
本实验是以数组的形式把线性表存放在计算机内存的一个连续的区域内,这样便有:LOC(ai+1)=LOC(ai)+mLOC(ai)=L0+m*(i-1)(二)程序说明插入一个新元素到第i个位置,既把元素ai向后移一个位置,成为元素ai+1,把新元素放入到第i个位置,其他元素依次后移。
插入后的表长是n+1(n 是原表长)。
修改第i个元素,到第i个位置是把元素ai冲掉后存上新值。
删除第i个元素就是把余后的元素依次向前移一个位置。
即:以元素ai+1,ai+2,···,依次取代ai,ai+1,···。
删除后的表长是n-1(n是原表长)。
三程序算法分析及实现(代码)一链表#include<stdio.h>#include<stdlib.h>struct linknode/*链表结构声明*/{int data; /*存储结点数据*/struct linknode *next; /*指向下一个结点*/};typedef struct linknode LinkNode; /*定义新类型*/LinkNode *CreatLinkNode() /*链表的创建*/{int i;LinkNode *head, *ptr, *p; /*链表结点*/head = (LinkNode *)malloc(sizeof(LinkNode)); /*分配内存*/ if (!head) /*检查指针内存是否分配成功*/{printf("内存分配失败!\n");exit(1); /*退出*/}printf("请输入第1个数据:");scanf("%d", &head->data); /*创建结点内容*/head->next = NULL; /*设置指针初值*/ptr = head; /*ptr指向链表开始*/for (i = 1; i<5; i++) /*循环创建结点*/{p = (LinkNode *)malloc(sizeof(LinkNode));if (!p){printf("内存分配失败!\n");exit(1);}printf("请输入第%d个数据:", i + 1);scanf("%d", &p->data);p->next = NULL;ptr->next = p; /*连接结点*/ptr = ptr->next; /*指向下一个结点*/}return head;}LinkNode *FindNode(LinkNode *head, int num) /*链表的遍历*/{LinkNode *ptr;ptr = head; /*指向链表起始*/while (ptr != NULL) /*遍历链表*/{if (ptr->data == num) return ptr; /*查找编号*/ptr = ptr->next; /*指向一下结点*/}return ptr;}LinkNode *InsertNode(LinkNode *head, LinkNode *ptr, int vlaue) /*链表结点的插入*/ {LinkNode *newnode = (LinkNode *)malloc(sizeof(LinkNode)); /*分配内存*/if (!newnode) return NULL;newnode->data = vlaue; /*创建结点内容*/newnode->next = NULL; /*设置指针初值*/if (ptr == NULL){newnode->next = head; /*新结点称为链表开始*/return newnode;}else{if (ptr->next == NULL) ptr->next = newnode; /*是否是链表结束指向新结点*/else{newnode->next = ptr->next; /*新结点指向下一个结点*/ptr->next = newnode; /*结点ptr指向新结点*/}}return head;}LinkNode *DeleteNode(LinkNode *head, LinkNode *ptr) /*链表结点删除*/{LinkNode *pre; /*指向前一结点*/if (ptr == head) /*是否是链表的开始*/return head->next; /*输出第二个结点*/else{pre = head;while (pre->next != ptr) /*找结点ptr的前结点*/pre = pre->next;if (ptr->next == NULL) /*是否是链表的结束*/pre->next = NULL; /*最后一个结点*/elsepre->next = ptr->next; /*中间结点*/ }free(ptr); /*释放结点内存*/return head;}void PrintNode(LinkNode *ptr) /*链表输出*/{while (ptr != NULL) /*链表遍历循环*/{printf("%d\t", ptr->data); /*输出结点数据*/ptr = ptr->next; /*指向下一结点*/}printf("\n");}void FreeLinkNode(LinkNode *head) /*链表的内存释放*/{LinkNode *ptr;while (head != NULL){ptr = head;head = head->next;free(ptr);}}int main(){int num, value;LinkNode *head, *ptr; /*指向链表开始*/head = CreatLinkNode(); /*创建链表*/PrintNode(head); /*输出链表*/printf("请输入要查找的数据:\n");scanf("%d", &num);ptr = FindNode(head, num); /*查询数据*/if (!ptr)printf("没有找到\n"); /*没有查询到*/else{printf("找到啦!\n请输入要插入的数据:\n");scanf("%d", &value);head = InsertNode(head, ptr, value); /*插入数据*/PrintNode(head); /*输出链表*/}printf("请输入要查找并删除的数据:\n");scanf("%d", &num);ptr = FindNode(head, num);if (!ptr)printf("没有找到\n");else{printf("找到\n");head = DeleteNode(head, ptr);PrintNode(head);}FreeLinkNode(head); /*释放链表*/return 0;}二顺序表#include<stdio.h>#include<stdlib.h>#define MAXLISTSIZE 1024 /* 定义顺序表最大容量 */typedef struct/* 定义顺序表节点类型 */{int data[MAXLISTSIZE]; /* 顺序表*/int last; /*顺序表元素个数 */}linearlist;void ListList(linearlist* list) /* 打印线性顺序表 */{int i;printf("当前线性表的状态:\n");if (list->last == 0) /*顺序表为空*/printf("当前顺序表为空");elsefor (i = 0; i < (list->last); i++) /*循环遍历顺序表*/printf("[%4d]", list->data[i]); /*输出元素*/printf("\n");}void Output(linearlist* list) /* 打印说明文档 */{system("cls"); /* 清屏 */printf("- 顺序表 -\n"); /* 输入功能菜单 */ printf("- a: 追加一个节点 i: 插入一个节点 -\n");printf("- d: 删除一个节点 e: 退出 -\n");ListList(list); /* 打印线性顺序表 */}linearlist* CreateList()/* 创建线性顺序表 */{linearlist *list = (linearlist*)malloc(sizeof(linearlist)); /* 分配空间 */ list->last = 0; /* 初始化头节点值 */return list; /* 返回初始化头节点指针 */}void AppendNode(linearlist* list, int n) /* 追加节点 */{if (list->last < MAXLISTSIZE) /*顺序表不溢出 */{list->data[list->last] = n; /* 初始化节点值 */list->last += 1; /* 顺序表长度加1 */}}void InsertNode(linearlist* list, int n, int pos) /* 插入节点 */{int j;if (pos < 0 || pos > list->last)printf("所插入的位置超出顺序表的范围\n");else{for (j = list->last; j >= pos; j--) /*逆向遍历顺序表*/list->data[j + 1] = list->data[j]; /*元素后移*/list->data[pos] = n; /*指向节点赋值*/list->last++; /* 顺序表长度加1 */}}void DeleteNode(linearlist* list, int pos) /* 删除节点 */{int j;if ((pos < 0) || (pos > list->last)) /* 删除位置超出顺序表的范围 */ printf("所要删除的位置超出顺序表的范围\n");else{for (j = pos; j < list->last; j++) /*遍历顺序表*/list->data[j] = list->data[j + 1]; /*元素前移*/list->last--; /* 顺序表长度减1 */}}int main(){int key, pos; /*key元素值,pos下标 */char ch;linearlist *list;list = CreateList(); /* 创建顺序表*/while (1){Output(list);printf("请选择:");ch = getchar(); /*接受选项*/fflush(stdin); /*清除缓存*/if (ch == 'a') /*追加*/{printf("请输入要追加的数据:");scanf("%d", &key);AppendNode(list, key);}else if (ch == 'i') /*插入*/{printf("请输入要插入的数据的位置:");scanf("%d", &pos);printf("请输入要插入的数据:");scanf("%d", &key);InsertNode(list, key, pos);}else if (ch == 'd') /*删除*/{printf("请输入要删除的数据的位置:");scanf("%d", &pos);DeleteNode(list, pos);}else if (ch == 'e') /*退出*/exit(0);Output(list);fflush(stdin); /*清除缓存*/}return 0;}四结果分析及测试相关记录链表:五实验体会和学习感悟刚接触数据结构时,觉得好难,学习了一段时间之后,发现果然如此。
数据结构上机实习报告
上机实习报告班号:116112姓名:**学号:***********实习报告【实习一】线性表及其应用n(n>20)的阶乘【问题描述】大数运算——计算n的阶乘(n>=20)。
【基本要求】(1)数据的表示和存储:(1.1)累积运算的中间结果和最终的计算结果的数据类型要求是整型——这是问题本身的要求;(1.2)试设计合适的存储结构,要求每个元素或结点最多存储数据的3位数值。
(2)数据的操作及其实现:基于设计的存储结构实现乘法操作,要求从键盘上输入n值,在屏幕上显示最终计算结果。
【问题分析】(1)设计数据的存储结构:介于乘运算的精确性以及实型数据表示的不精确性,本题不能采用实型表示累积运算的中间结果和最终的计算结果,而只能用整型。
然而由于普通整型和长整型所能表述数的范围受其字长的限制,不能表示大数阶乘的累积结果,故必须设计一个合适的数据结构实现对数据的存储,例如可以让每个元素或结点存储数据的若干位数值。
从问题描述不难看出n值为任意值,故为使程序尽量不受限制,应采用动态存储结构。
累积运算的特点是当前的计算结果是下次乘法运算的乘数。
实现两个数的乘法运算须考虑:(1)乘数的各位数都要与被乘数进行乘法运算;(2)乘法过程中的进位问题及其实现;(3)因每个元素或结点最多存储数据的3位数值,故当元素或结点中的数值大于999,需向前一个元素或结点进位。
综合以上几点,我采用了单链表的储存结构形式。
(2)阶乘算法的实现:1. 链表型数据乘法的具体实现描述:(1)初始算法顺序访问对每个节点上的数据乘以要乘的数后在顺序访问查看是否需要进位,大于999则向前进位,如果前面没有节点则添加新节点储存进位的数(2)改进算法将原始算法的乘操作和进位操作合在一起进行,提高程序效率.2. 数据输出算法具体实现描述从高位向低位顺序输出节点上储存的数据,注意补零,最高位的节点不补,其它节点要补。
对于最后的结果,因为我采用的是普通的单链表算法,因此我添加了一个逆置的算法。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
数据结构上机报告(三)多项式的存储与运算一.问题提出:实现单向链表的基本功能,基本功能如下:(1)创建单链表(2)插入表元素(3)删除表元素(4)获取表元素(5)获取表长度(6)展示单链表(7)销毁单链表二.问题分析及算法设计:这是一个关于单向链表的最基本的程序操作问题,按照单向链表的相关定义,正常编写程序即可,并没有特别之处。
三.程序设计:1.定义结构体,结构体包含数域、指针域以及功能函数;2.功能函数的声明与定义:(1)创建单链表函数:LNodeCreat(LNode *&L);(2)插入元素函数:LNodeInsert(LNode *&L);(3)删除元素函数:LNodeDelete(LNode *&L);(4)获取元素函数:LNodeGet(LNode *&L);(5)展示单链表函数:LNodeShow(LNode *&L);(6)单链表长度函数:LNodeLength(LNode *&L);(7)销毁单链表函数:LNodeDestroy(LNode *&L);3.立主函数main函数,实现数组的输入与输出,同时利用switch函数,调取上述功能函数;4.定义display()函数,在运行界面上显示出功能表。
四.用户手册:(1)运行程序;(2)根据功能菜单栏,输入“1”,创建一个单向链表,依次输入元素个数以及元素值。
(3)选择输入1-7,进行相关的单向链表基本功能操作;(4)输入8,结束运行。
(5)运行结果示意图如下:五.调试报告:(1)编写LNodeInsert(LNode*&L)函数时,for循环中判定语句for (i = 1; i < a&&q!=NULL; i++)中的“&&”只写了一个“&”,导致运行出错。
经过仔细检查后得以改正。
(2)编写时,有两个“;”写成了中文的分号,不易察觉。
由此可知编程是一件十分考验耐心与细心的事,一点点小细节就可以决定你的程序能否正常运行。
所以,在以后的编程实践中一定要更加细心才可以。
六.附录:程序代码#include<iostream>using namespace std;struct LNode//定义结构体{int Data; //数据域LNode *next; //指针域};void disp(); //功能表函数void LNodeCreat(LNode *&L); //创建单链表函数函数void LNodeInsert(LNode *&L); //向单链表中插入元素函数void LNodeDelete(LNode *&L); //从单链表中删除元素函数void LNodeGet(LNode *&L); //从单链表中获取元素函数void LNodeShow(LNode *&L); //展示单链表中现有元素函数void LNodeLength(LNode *&L); //计算单链表现有长度函数void LNodeDestroy(LNode *&L); //销毁单链表函数void main(){LNode *M;int a;for (int j = 0; j < 1;){disp();cin >> a;switch (a) //选项{case 1:LNodeCreat(M); break;case 2:LNodeInsert(M); break;case 3:LNodeDelete(M); break;case 4:LNodeGet(M); break;case 5:LNodeLength(M); break;case 6:LNodeShow(M); break;case 7:LNodeDestroy(M); break;case 8:j = 1; break;default:cout <<" 没有此功能选项! "<< endl;}}}void disp(){cout << "-----------------------------------请选择功能-----------------------------------" << endl;cout << '\t' << "1.创建单链表" << '\t' << "2.插入表元素" << '\t' << "3.删除表元素" <<'\t'<<"4.获取表元素"<<endl;cout << '\t' << "5.获取表长度" << '\t' << "6.展示单链表" << '\t' << "7.销毁单链表" <<'\t'<<"8.退出"<< endl<<endl;cout <<"--------------------------------------------------------------------------------" << endl;};void LNodeCreat(LNode *&L){int n;cout << "请输入要创建单链表的元素个数" << endl;cin >> n;cout << "请依次输入单链表元素,按Enter键输入" << endl;L = new LNode[sizeof(LNode)];L->next = NULL; //定义带头节点的单链表LLNode *q = L;LNode *p;for (int i = 1; i <= n; i++){p=new LNode[sizeof(LNode)]; //创建新的节点,赋值后加到单链表中cin >> p->Data;p->next = q->next;q->next = p;q = p;}cout << "单链表创建完成!" << endl;void LNodeInsert(LNode *&L){int a, b;int i = 1;cout << "请输入要插入元素的位置和数据,按Enter确定" << endl;cin >> a >> b;LNode *q = L;for (i = 1; i < a&&q!=NULL; i++){q = q->next;}if (i<a||q==NULL)cout << "链表长度小于"<<a<< endl;else{LNode *p = new LNode[sizeof(LNode)];p->Data = b;p->next = q->next;q->next = p;cout << "数据" << b << "已成为链表中第" << a << "个元素" << endl;}};void LNodeDelete(LNode *&L){LNode *q = L;LNode *p;int n;int i;cout << "请输入要删除元素的位置" << endl;cin >> n;for (i = 1; i < n&&q->next!=NULL; i++){q = q->next;}if (i<n||q->next==NULL)cout << "链表长度小于" << n << endl;else{p = q->next;q->next = p->next;delete p;cout << "第" << n << "个元素已被删除" << endl;}void LNodeGet(LNode *&L){int n;int i;LNode *q = L;cout << "请输入要得到的元素的位置" << endl;cin >> n;for (i = 1; i <=n&&q!=NULL; i++){q = q->next;}if (i<n||q==NULL)cout << "链表长度小于" << n << endl;else{cout << "第" << n << "个元素数据为:" << q->Data << endl;}};void LNodeShow(LNode *&L){cout << "该链表现有元素为:";LNode *q = L;while (q->next!= NULL){q = q->next;cout << q->Data << "\t";}cout << endl;};void LNodeLength(LNode *&L){LNode *q = L;int n = 0;while (q->next != NULL){q = q->next;n++;}cout << "单链表长度为:" << n << endl;};void LNodeDestroy(LNode *&L){LNode *q = L;while (q->next != NULL){LNode *p = q->next;q->next = p->next;delete p; //释放p节点}delete q; //释放头节点cout << "链表已销毁" << endl;};2015.3。