数据结构课程设计+数据汇总超市.docx
- 文档编号:27319624
- 上传时间:2023-06-29
- 格式:DOCX
- 页数:39
- 大小:183.01KB
数据结构课程设计+数据汇总超市.docx
《数据结构课程设计+数据汇总超市.docx》由会员分享,可在线阅读,更多相关《数据结构课程设计+数据汇总超市.docx(39页珍藏版)》请在冰豆网上搜索。
数据结构课程设计+数据汇总超市
得分:
信电工程学院
课程设计报告
数据汇总系统
课程:
高级语言程序设计
班级:
12软件1
学号:
20120510116
姓名:
潘焕燚
指导教师:
丁宾
2013年7月1日
1程序目标及功能---------------------------------------------------------------1
1.1课题背景-----------------------------------------------------------------1
1.2系统功能---------------------------------------------------------------3
1.3设计要求---------------------------------------------------------------3
2程序功能模块组成及流程图------------------------------------------------4
2.2系统功能模块-----------------------------------------------------------4
2.3各模块流程图-----------------------------------------------------------5
3程序主要数据结构及函数列表---------------------------------------------8
3.1程序中使用的数据结构----------------------------------------------8
3.2函数列表--------------------------------------------------------------10
4程序代码及运行结果-------------------------------------------------------14
5总结与体会------------------------------------------------------------------32
题目:
数据汇总
题目内容:
在数据处理中经常需要对大量数据进行汇总,将相同关键字记录的某些数据项的值叠加起来,生成一个分类汇总表。
假设某超级市场销售有m种商品(假设商品的编号为1,2,3,┅┅,m),有n台前台收款机(假设收款机的编号为1,2,3,┅┅,n)进行收款,以记录的形式提供给计算机,每个记录表示某台收款机的一种商品一次交易的数量和销售额。
记录由4个域组成:
收款机编号、商品编号、销售数量、销售金额。
构造一个结构体类型,每次销售数据以一个结构体变量保存在一个数据文件中。
本人完成的工作:
(1)编写实现将数据记录插入到数据文件的最后的函数;
⑵编写以收款机为单位的数据分类处理函数。
构造n个单链表,每个链表保存一台收款机的销售记录,这n个单链表的头指针存放在一个指针数组中,通过数组的下标就可以知道是哪台收款机。
读取数据文件的记录,将所有的销售记录(数据文件中的全部记录)分解插入到n个单链表;
(3)编写以商品为单位的数据分类处理函数。
构造m个单链表,每个链表保存一种商品的销售记录,这m个单链表的头指针存放在一个指针数组中,通过数组的下标就可以知道是哪种商品。
读取数据文件的记录,将所有的销售记录(数据文件中的全部记录)分解插入到m个单链表;
(4)统计每台收款机的销售总额;
(5)以收款机为单位,将所有收款机按销售总额的递增顺序构造一个单链表并输出。
(6)以商品为单位,统计每种商品的销售总额。
(7)以商品为单位,将所有销售的商品按销售总额的递增顺序构造一个单链表并输出。
(8)设计一个菜单,具有插入数据记录、按收款机统计销售总额、按商品统计销售总额、退出系统等最基本的功能。
所采用的数据结构:
单链表
销售商品数据记录结构定义:
typedefstructGoods
{
intregNum;//收款机编号
intgoodsNum;//商品编号
intsalesVol;//销售数量
doublesalesAmount;//销售单价
}Goods;
typedefstructGoodsElemType;//用于链表里的数据类型
单链表结点定义:
typedefstructNode
{
ElemTypedata;//链表所存的数据
structNode*next;//指向下一个结点的指针
}*LNode,*LinkList;
所设计的函数:
[1].将数据记录插入到文件data.dat最后的函数
intAddrecord(Goods*goods)
算法思想:
首先判断参数是否非法,非法则返回FAIL,否则以以二进制的append方式打开文件data.dat;文件指针为空则打开失败返回FAIL,否则将数据记录写入文件,然后关闭文件,返回SUCCESS。
流程图:
开始
参数为空?
返回FAIL
结束
是
打开文件失败?
是
否
否
把记录写入文件
关闭文件,返回SUCCESS
[2].以收款机为单位的数据分类处理函数
LinkList*SortByReg(intn)
算法思想:
判断打开文件是否成功,失败则打印“打开文件失败”并返回FAIL,否则分配链表指针数组;然后判断内存是否充足,不足则打印“内存不足”并返回FAIL,否则初始化n个收款机链表,并读相应记录,存到对应的收款机链表中的末尾结点,最后关闭文件,返回链表数组。
流程图:
开始
打开文件失败?
打印“打开文件失败”
返回“FAIL”
结束
是
分配链表指针数组
内存不足?
打印“内存不足”
否
是
初始化n个收款机链表
否
读相应记录
关闭文件,返回链表数组
数据块个数不为1?
是
链表为空?
否
初始化链表
是
将记录存到相应链表的末尾结点
否
[3]统计每台收款机的销售总额
double*SumByReg(intn)
算法思想:
申请一个数组存储各台收款机的销售总额,申请不成功则打印“内存不足”并返回FAIL,否则调用SortByReg(n)函数得到分类好的收款机链表指针数组,判断指针数组是否为空,是则释放之前时申请的内存空间并返回NULL,否则初始化总额数组,并进行累计分析,之后释放收款机的链表内存,释放链表指针的内存,释放总额数组,返回总额amount
流程图:
[4].以商品为单位的数据分类处理函数
LinkList*SortByGoods(intm)
算法思想:
判断打开文件是否成功,失败则打印“打开文件失败”并返回FAIL,否则分配链表指针数组;然后判断内存是否充足,不足则打印“内存不足”并返回FAIL,否则初始化m个商品链表,并读相应记录,存到对应的商品链表中的末尾结点,最后关闭文件,返回链表数组。
流程图:
开始
打开文件失败?
打印“打开文件失败”
返回“FAIL”
结束
是
分配链表指针数组
内存不足?
打印“内存不足”
否
是
初始化m个商品链表
否
读相应记录
关闭文件,返回链表数组
数据块个数不为1?
是
链表为空?
否
初始化链表
是
将记录存到相应链表的末尾结点
否
[5].以商品为单位,统计每种商品的销售总额
double*SumByGoods(intm)
算法思想:
申请一个数组存储各种商品的销售总额,申请不成功则打印“内存不足”并返回FAIL,否则调用SortByGoods(m)函数得到分类好的各种商品的链表指针数组,判断指针数组是否为空,是则释放之前时申请的内存空间并返回NULL,否则初始化总额数组,并进行累计分析,之后释放收款机的链表内存,释放链表指针的内存,释放总额数组,返回总额amount
流程图:
开始
结束
申请一个数组储存各种商品的销售总额
内存不足?
否
是
打印“内存不足”
返回“FAIL”
调用SortByGoods(m)函数得到分类好的商品链表指针数组
指针数组为空?
释放之前申请的内存
返回NULL
是
初始化总额数组
否
记录总额累加
释放链表头指针的内存,释放总额数组
返回总额amount
初始化参数i=0
i 是 链表regArr[i]为空? 否 链表长度为recs recs-->0? 结果打印,释放收款机的链表内存 是 i++ 否 是 否 [6].设计一个菜单,具有插入数据记录、按收款机统计销售总额 voidRunMenu(void) 算法思想: 开始 清除以前的无关输入 打印菜单 根据选择的菜单项进行相应的操作 结束 1.插入数据记录 2.按收款机统计销售总额 4退出系统 3.按商品统计销售总额 清除以前的无关输入,打印菜单,根据选择的菜单项进行相应的操作。 [7].用于输入一条新的记录 开始 goods->regNum>0&&goods->regNum<=allRegisters? 打印“请输入商品信息” 清除缓冲区 输入收款机编号 是 否 打印“收款机编号(1--%d): #” 清除缓冲区 输入商品编号 goods->goodsNum>0&&goods->goodsNum<=allGoods? 是 否 打印“商品编号(1--%d): #” 打印“销售数量: n=” 输入销售数量 打印“销售单价” 输入单价 清除缓冲区 结束 [8].GOODS的输出函数 开始 count=ListLength(L) L==NULL? node=L->next node==NULL? 打印记录格式 i=0 i 输出记录 (i+1)%5==0? getch() i++; node=node->next; 输出总额和记录条数 是 否 否 否 是 是 结束 程序运行结果: 1: 主程序运行,菜单打印 2插入数据记录 3.按收款机统计销售总额 4.按商品统计销售总额 5.按商品销售记录排序 6按收款机收款纪录排序 7退出系统 源程序: #include #include #include #defineSUCCESS1//操作成功 #defineFAIL0//操作失败 #defineallRegisters15 #defineallGoods30 //销售的商品数据记录 typedefstructGoods { intregNum;//收款机编号 intgoodsNum;//商品编号 intsalesVol;//销售数量 doublesalesAmount;//销售单价 }Goods; typedefstructGoodsElemType;//用于链表里的数据类型 typedefstructNode { ElemTypedata;//链表所存的数据 structNode*next;//指向下一个结点的指针 }*LNode,*LinkList; //构造一个空的线性表 LinkListInitList(void) { LNodeHead; Head=(LNode)malloc(sizeof(structNode));//为链表的头结点分配空间 if(! Head) { printf("Outofspace! "); returnNULL; } Head->next=NULL; returnHead;//返回头结点,第一个结点head是不存任何数据的 } //初始条件: 线性表L已存在。 操作结果: 返回线性表L的最后一个结点(尾结点)。 LNodeIsLast(LinkListL) { LNodeP=L->next; if(P) { while(P->next! =NULL)//遍历线性表L P=P->next; returnP;//返回线性表L的最后一个结点 } else returnL;//链表只有头结点,而它不存数据的 } //初始条件: 线性表L已存在。 操作结果: 返回线性表L结点的个数。 intListLength(LinkListL) { LNodeP=L->next; intnum=0; while(P)//累积线性表L结点的个数 { num++; P=P->next; } returnnum;//返回线性表L结点的个数 } //构造一个数据域为X的新结点 LNodeNewLNode(ElemTypeX) { LNodeS; S=(LNode)malloc(sizeof(structNode));//为新结点分配空间 if(! S) { printf("Outofspace! "); returnNULL; } S->data=X; S->next=NULL; returnS;//返回新结点 } //初始条件: 线性表L已存在。 操作结果: 销毁线性表L。 voidDestroyList(LinkList*L) { LNodeHead,P; if(*L)//若线性表L已存在 { Head=*L; P=Head->next; while(P! =NULL)//把链表中除头结点外的所有结点释放 { free(Head); Head=P; P=Head->next; } free(Head);//释放头结点 } *L=NULL; } //初始条件: 线性表L中结点P已找到,新结点S已构造。 。 操作结果: 在该结点之后插入新结点X。 voidListInsert(LNodePre,LNodeS) { S->next=Pre->next; Pre->next=S; } //用于输入一条新的记录 //缺点就是没对输入的数据各种检查 //一旦输入字母就不行了 Goods*Newrecord(Goods*goods) { printf("----------------------------\n" "请输入商品信息: \n"); //收款台号,保证录入正确的数据 while (1) { fflush(stdin); printf("收款机编号(1--%d): #",allRegisters); scanf("%d",&goods->regNum); if(goods->regNum>0&&goods->regNum<=allRegisters) break; } //商品号 while (1) { fflush(stdin); printf("商品编号(1--%d): #",allGoods); scanf("%d",&goods->goodsNum); if(goods->goodsNum>0&&goods->goodsNum<=allGoods) break; } //销售量 printf("销售数量: n="); scanf("%d",&goods->salesVol); //销量单价 printf("商品销售单价: $"); scanf("%lf",&goods->salesAmount); //清除可能输入缓冲区 fflush(stdin); returngoods; } //专为GOODS而写的输出函数 voidListPrint(LinkListL,doubleamount) { LNodenode; inti; intcount=ListLength(L); if(L==NULL) return; //第一个结点不存记录,所以从第二个开始 node=L->next; if(node==NULL) return; //打印出表头 printf("注意: 每打印5个记录,将会暂停,按enter继续! ! \n"); printf("收款机No(R).|商品No(G).|单价($)|销售数量(n)\n"); //将全部记录按格式打印出来 i=0; while(i { printf("R*%-15dG*%-13d$%-14.2lfn=%-13d\n", node->data.regNum,node->data.goodsNum,node->data.salesAmount,node->data.salesVol); if((i+1)%5==0) getch(); i++; node=node->next; } //这个就是打出总额了,Total则是记录的条数 printf("销售总额=%lf,记录条数=%d\n",amount,i); } //[1].将数据记录插入到文件data.dat最后的函数 intAddrecord(Goods*goods) { FILE*ofp; //非法参数 if(goods==NULL) returnFAIL; //以二进制的append方式打开文件data.dat if((ofp=fopen("data.dat","ab"))==NULL) { printf("Openfail! \n"); returnFAIL; } //把记录写入文件中 fwrite(goods,sizeof(structGoods),1,ofp); //关闭文件 fclose(ofp); returnSUCCESS; } //[2].编写以收款机为单位的数据分类处理函数 LinkList*SortByReg(intn) { inti,count; FILE*ifp; Goodstemp; LinkList*regArr;//收款机的链表数组 if((ifp=fopen("data.dat","rb"))==NULL) { printf("OpenFail.\n"); returnFAIL; } //分配链表指针数组 regArr=(LinkList*)malloc(n*sizeof(LinkList)); if(regArr==NULL) { printf("Notenoughmemory\n"); returnFAIL; } //n个收款机链表初始化 for(i=0;i regArr[i]=NULL; //开始根据收款机的编号将所读的记录进行分类 //注意数组下标是从0开始,而收款机是从1开始数的 while (1) { //读相应的记录,正确读取时count为所读的字节数 count=fread(&temp,sizeof(structGoods),1,ifp); //出错或是到文件尾了 if(count! =1) break; //第一次要初始化链表 if(regArr[temp.regNum-1]==NULL) regArr[temp.regNum-1]=InitList(); //存到对应的收款机链表中的末尾结点 ListInsert(IsLast(regArr[temp.regNum-1]),NewLNode(temp)); } //关闭文件 fclose(ifp); returnregArr; } //[3]统计每台收款机的销售总额 double*SumByReg(intn) { inti,recs; double*amount; LNodenode; LinkList*regArr; //申请一个数组存储各台收款机的销售总额 if((amount=(double*)malloc(n*sizeof(double)))==NULL) { printf("Notenoughmemory! \n"); returnFAIL; } //得到了分类好的收款机链表指针数组 regArr=SortByReg(n); if(regArr==NULL) { free(amount);//释放之前申请的内存 returnNULL; } //初始化总额数组 for(i=0;i amount[i]=0; //进行分析累加 for(i=0;i { if(regArr[i]==NULL) continue; //链表头是不存任何数据的 node=regArr[i]->next; //链表是空的 if((recs=ListLength(regArr[i]))==0) continue; //遍历一个收款机链表里有的所有记录 while(recs-->0) { //将该台收款机销售的商品记录的总额进行累加 amount[i]+=node->data.salesAmount*node->data.salesVol; node=node->next; } } //释放收款机的链表内存 for(i=0;i { if(regArr[i]==NULL) continue; //打印出后再释放内存 ListPrint(regArr[i],amount[i]); DestroyList(®Arr[i]); } //释放链表指针头的内存 free(regArr); //释放总额数组 free(amount); returnamount; } //[4]排序收款机销售总额 double*PaixuByR
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 数据结构 课程设计 数据 汇总 超市