车票管理系统.docx
《车票管理系统.docx》由会员分享,可在线阅读,更多相关《车票管理系统.docx(21页珍藏版)》请在冰点文库上搜索。
![车票管理系统.docx](https://file1.bingdoc.com/fileroot1/2023-7/13/f72edd7b-cf68-47fa-90e5-5291e890bbff/f72edd7b-cf68-47fa-90e5-5291e890bbff1.gif)
车票管理系统
二○一○~二○一一学年第二学期
信息科学与工程学院
课程设计报告书
课程名称:
数据结构课程设计
班级:
电信(DB)1003班
学号:
201012135109
姓名:
徐潇
指导教师:
姚刚霞
二○一一年十二月
一、前言
1.摘要
2.《数据结构与算法》课程设计任务书
二、实验目的
三、题目—哈夫曼编码/译码器
1.问题描述
2.基本要求
3.测试要求
4.实现提示
四、需求分析--具体要求
五、概要设计
六、程序说明
七、详细设计
八、实验心得与体会
前言
1.摘要
随着计算机的普遍应用与日益发展,其应用早已不局限于简单的数值运算,而涉及到问题的分析、数据结构框架的设计以及设计最短路线等复杂的非数值处理和操作。
算法与数据结构的学习就是为以后利用计算机资源高效地开发非数值处理的计算机程序打下坚实的理论、方法和技术基础。
算法与数据结构旨在分析研究计算机加工的数据对象的特性,以便选择适当的数据结构和存储结构,从而使建立在其上的解决问题的算法达到最优。
数据结构是在整个计算机科学与技术领域上广泛被使用的术语。
它用来反映一个数据的内部构成,即一个数据由那些成分数据构成,以什么方式构成,呈什么结构。
数据结构有逻辑上的数据结构和物理上的数据结构之分。
逻辑上的数据结构反映成分数据之间的逻辑关系,而物理上的数据结构反映成分数据在计算机内部的存储安排。
数据结构是数据存在的形式。
《数据结构》主要介绍一些最常用的数据结构,阐明各种数据结构内在的逻辑关系,讨论其在计算机中的存储表示,以及在其上进行各种运算时的实现算法,并对算法的效率进行简单的分析和讨论。
数据结构是介于数学、计算机软件和计算机硬件之间的一门计算机专业的核心课程,它是计算机程序设计、数据库、操作系统、编译原理及人工智能等的重要基础,广泛的应用于信息学、系统工程等各种领域。
学习数据结构是为了将实际问题中所涉及的对象在计算机中表示出来并对它们进行处理。
通过课程设计可以提高学生的思维能力,促进学生的综合应用能力和专业素质的提高。
2.《数据结构与算法》课程设计任务书
《数据结构与算法》是计算机专业重要的核心课程之一,在计算机专业的学习过程中占有非常重要的地位。
《数据结构与算法课程设计》就是要运用本课程以及到目前为止的有关课程中的知识和技术来解决实际问题。
特别是面临非数值计算类型的应用问题时,需要选择适当的数据结构,设计出满足一定时间和空间限制的有效算法。
本课程设计要求同学独立完成一个较为完整的应用需求分析。
并在设计和编写具有一定规模程序的过程中,深化对《数据结构与算法》课程中基本概念、理论和方法的理解;训练综合运用所学知识处理实际问题的能力,强化面向对象的程序设计理念;使自己的程序设计与调试水平有一个明显的提高。
二、实验目的
数据结构作为一门学科主要研究数据的各种逻辑结构和存储结构,以及对数据的各种操作。
因此,主要有三个方面的内容:
数据的逻辑结构;数据的物理存储结构;对数据的操作(或算法)。
通常,算法的设计取决于数据的逻辑结构,算法的实现取决于数据的物理存储结构。
数据结构是信息的一种组织方式,其目的是为了提高算法的效率,它通常与一组算法的集合相对应,通过这组算法集合可以对数据结构中的数据进行某种操作。
在当今信息时代,信息技术己成为当代知识经济的核心技术。
我们时刻都在和数据打交道。
比如人们在外出工作时找最短路径,在银行查询存款、通过互联网查新闻、以及远程教育报名等,所有这些都在与数据发生关系。
实际上,现实世界中的实体经过抽象以后,就可以成为计算机上所处理的数据。
数据结构课程主要是研究非数值计算的程序设计问题中所出现的计算机操作对象以及它们之间的关系和操作的学科。
数据结构是介于数学、计算机软件和计算机硬件之间的一门计算机专业的核心课程,它是计算机程序设计、数据库、操作系统、编译原理及人工智能等的重要基础,广泛的应用于信息学、系统工程等各种领域。
学习数据结构是为了将实际问题中所涉及的对象在计算机中表示出来并对它们进行处理。
通过课程设计可以提高学生的思维能力,促进学生的综合应用能力和专业素质的提高。
通过此次课程设计主要达到以下目的:
了解并掌握数据结构与算法的设计方法,具备初步的独立分析和设计能力;
初步掌握软件开发过程的问题分析、系统设计、程序编码、测试等基本方法和技能;
提高综合运用所学的理论知识和方法独立分析和解决问题的能力;
训练用系统的观点和软件开发一般规范进行软件开发,培养软件工作者所应具备的科学的工作方法和作风。
三、题目哈夫曼编码/译码器
1.问题描述
利用赫夫曼编码进行通信可以大大提高信道利用率,缩短信息传输时间,降低传输成本。
这要求在发送端通过一个编码系统对待传输数据预先编码,在接收端将传来的数据进行译码(复原)。
对于双工信道(即可以双向传输信息的信道),每端都需要一个完整的编/译码系统。
试为这样的信息收发站编写一个赫夫曼码的编/译码系统。
2.基本要求
一个完整的系统应具有以下功能:
(1)I:
初始化(Initialization)。
从终端读入字符集大小n,以及n个字符和n个权值,建立赫夫曼树,并将它存于文件hfmTree中。
(2)E:
编码(Encoding)。
利用已建好的赫夫曼树(如不在内存,则从文件hfmTree中读入),对文件ToBeTran中的正文进行编码,然后将结果存入文件CodeFile中。
(3)D:
译码(Decoding)。
利用已建好的赫夫曼树将文件CodeFile中的代码进行译码,结果存入文件Textfile中。
四、具体要求:
课程设计成果的内容必须由以下四个部分组成,缺一不可。
(1)上交源程序:
学生按照实验题目的具体要求所开发的所有源程序(应该放到一个文件夹中);
(2)上交程序的说明文件:
(保存在.txt中)在说明文档中应该写明上交程序所在的目录,上交程序的主程序文件名,如果需要安装,要有程序的安装使用说明;
(3)设计报告:
(保存在word文档中,文件名要求:
按照“姓名_学号_设计题目”起名,如文件名为“张三_XXX_赫夫曼编码”.doc。
打印稿用A4纸)。
其中包括:
♦题目;
♦实验目的;
♦需求分析:
在该部分中叙述实现的功能要求;
♦概要设计:
在此说明每个部分的算法设计说明(可以是描述算法的流程图),每个程序中使用的存储结构设计说明(如果指定存储结构请写出该存储结构的定义);
♦详细设计
各个算法实现的源程序,对每个题目要有相应的源程序(可以是一组源程序,每个功能模块采用不同的函数实现)。
源程序要按照写程序的规则来编写。
要结构清晰,重点函数的重点变量、重点功能部分要加上清晰的程序注释;
♦调试分析
测试数据,测试输出的结果,时间复杂度分析,和每个模块设计和调试时存在问题的思考(问题是哪些?
问题如何解决?
),算法的改进设想;
♦总结:
总结可以包括:
设计过程的收获、遇到问题及解决问题过程的思考、程序调试能力的思考、对数据结构这门课程的思考、在设计过程中对《数据结构》课程的认识等内容。
(4)考核成绩评定标准:
本课程设计的评价由三部分组成,包括程序演示(50%),课程设计报告(30%),回答教师提问(20%)。
1.程序演示:
Ø优功能完善,全部测试正确,并且能够对局部进行完善。
Ø良功能完善,但测试欠缺。
Ø中功能基本完善,但程序尚有部分错误。
Ø及格完成内存中赫夫曼编码/译码,但不涉及文件操作。
Ø不及格功能不完善,且程序错误较多,无法运行。
2.课程设计报告:
1.优包括设计内容,设计思想,已经完成的任务及达到的目标,设计思路清晰、书写条理清楚,源程序结构合理、清晰,注释说明完整,有对本次课程设计的心得体会。
2.良包括设计内容,设计思想,已经完成的任务及达到的目标,设计思路基本清晰、书写条理基本清楚,源程序结构合理、清晰,注释说明基本完整,有对本次课程设计的心得体会。
3.中课程设计报告内容基本完整,思路较清晰,书写基本清楚,源程序结构尚可,有注释说明但不完整。
4.及格课程设计报告内容基本完整,思路较差,书写尚清楚。
5.不及格课程设计报告内容不完整,书写没有条理。
五.概要设计
首先我编程了几个字符串处理函数如:
linktreetidycharacter(charcharacter[])(整理输入的字符串,合并相同的项,并求出每个字符在数组中出现的次数)linktreedeal(linktreetree)(将整理完的字符串按出现次数从小到大的顺序排列)建立哈夫曼函数linktreecreateHftree(linktreetree)(用排完序的字符串建立哈夫曼树),编码函数voidHuffmancoding(linktreetree)(对哈夫曼树进行编码)译码函数voiddecode(linktreetree,charcode[]);之后在主函数中调用它们实现了程序的模块化,便于修改程序和程序的升级
六.程序演示
1.进入主界面会显示如下图的界面,且每一次都会回到该界面使得文件的可读性很好。
选择A进入编码界面。
会输出哈夫曼的编码!
会返回到当初的主界面,
2.按进入编译界面
会显示出编码的
3.按c会退出;
七.心得体会
在我自己课程设计中,就在编写好源代码后的调试中出现了不少的错误,遇到了很多麻烦及困难,我的调试及其中的错误和我最终找出错误,修改为正确的能够执行的程序中,通过分析,我学到了:
在定义头文件时可多不可少,即我们可多写些头文件,肯定不会出错,但是若没有定义所引用的相关头文件,必定调试不通过;
在执行译码操作时,不知什么原因,总是不能把要编译的二进制数与编译成的字符用连接号连接起来,而是按顺序直接放在一起,视觉效果不是很好。
还有就是,很遗憾的是,我们的哈夫曼编码/译码器没有像老师要求的那样完成编一个文件的功能,这是我们设计的失败之处。
通过本次数据结构的课程设计,我学习了很多在上课没懂的知识,并对求哈夫曼树及哈夫曼编码/译码的算法有了更加深刻的了解,更巩固了课堂中学习有关于哈夫曼编码的知识,真正学会一种算法了。
当求解一个算法时,不是拿到问题就不加思索地做,而是首先要先对它有个大概的了解,接着再详细地分析每一步怎么做,无论自己以前是否有处理过相似的问题,只要按照以上的步骤,必定会顺利地做出来。
这次课程设计,我在编辑中犯了不应有的错误,设计统计字符和合并时忘记应该怎样保存数据,对文件的操作也很生疏。
在不断分析后明确并改正了错误和疏漏,我的程序有了更高的质量。
(源程序附在后面)
电信(DB)1003班
徐潇:
201012135109
#include
#include//要用system函数要调用的头文件
#include//用getch()要调用的头文件
#include
#defineMAXLEN100
typedefstructHuffmantree
{
charch;
intweight,mark;
structHuffmantree*parent,*lchild,*rchild,*next;
}Hftree,*linktree;
/**************************字符串处理函数*****************************/
linktreetidycharacter(charcharacter[])/*整理输入的字符串,合并相同的项,并求出每个字符在数组中出现的次数*/
{
inti=0;
linktreetree,ptr,beforeptr,node;
tree=(linktree)malloc(sizeof(Hftree));/*创建单链表的头结点*/
if(!
tree)returnNULL;
tree->next=NULL;
for(i=0;character[i]!
='\0'&&character[i]!
='\n';i++)
{
ptr=tree;
beforeptr=tree;
node=(linktree)malloc(sizeof(Hftree));
if(!
node)returnNULL;
node->next=NULL;
node->parent=NULL;
node->lchild=NULL;
node->rchild=NULL;
node->mark=0;
node->ch=character[i];
node->weight=1;
if(tree->next==NULL)
tree->next=node;
else{
ptr=tree->next;
while(ptr&&ptr->ch!
=node->ch){/*将指针移至链表尾*/
ptr=ptr->next;
beforeptr=beforeptr->next;
}
if(ptr&&ptr->ch==node->ch){/*如果链表中某结点的字符与新结点的字符相同*/
/*将该结点的权加一*/
ptr->weight=ptr->weight+1;
free(node);
}
else{/*将新结点插入链表后*/
node->next=beforeptr->next;
beforeptr->next=node;
}
}
}
returntree;
}
/*****************************字符串整理函数******************************/
linktreedeal(linktreetree)/*将整理完的字符串按出现次数从小到大的顺序排列*/
{
linktreehead,ph,pt,beforeph;
head=(linktree)malloc(sizeof(Hftree));/*创建新链表的头结点*/
if(!
head)returnNULL;
head->next=NULL;
ph=head;
beforeph=head;
while(tree->next){
pt=tree->next;/*取被操作链表的首元结点*/
tree->next=pt->next;
pt->next=NULL;
ph=head->next;
beforeph=head;
if(head->next==NULL)
head->next=pt;/*创建当前操作链表首元结点*/
else{
while(ph&&ph->weightweight){/*将被操作结点插入相应位置*/
ph=ph->next;
beforeph=beforeph->next;
}
pt->next=beforeph->next;
beforeph->next=pt;
}
}
free(tree);
returnhead;
}
/**************************建立二叉树函数*****************************/
linktreecreateHftree(linktreetree)/*用排完序的字符串建立哈夫曼树*/
{
linktreep,q,newnode,beforep;
for(p=tree->next,q=p->next;p!
=NULL&&q!
=NULL;p=tree->next,q=p->next){
tree->next=q->next;
q->next=NULL;
p->next=NULL;
newnode=(linktree)malloc(sizeof(Hftree));/*申请新结点作为哈夫曼树的中间结点*/
if(!
newnode)returnNULL;
newnode->next=NULL;
newnode->mark=0;
newnode->lchild=p;/*取链表头结点后的两个结点作为新结点的左、右儿子*/
newnode->rchild=q;
p->parent=newnode;
q->parent=newnode;
newnode->weight=p->weight+q->weight;
p=tree->next;
beforep=tree;
if(p!
=NULL&&p->weight>=newnode->weight){/*将新结点插入原链表的相应位置*/
newnode->next=beforep->next;
beforep->next=newnode;
}
else{
while(p!
=NULL&&p->weightweight){
p=p->next;
beforep=beforep->next;
}
newnode->next=beforep->next;
beforep->next=newnode;
}
}
return(tree->next);
}
/***********************哈夫曼编码函数***************************/
voidHuffmancoding(linktreetree)/*对哈夫曼树进行编码*/
{
intindex=0;
char*code;
linktreeptr=tree;
code=(char*)malloc(10*sizeof(char));/*此数组用于统计哈夫曼编码*/
printf("字符以及它的相应权数---------霍夫曼编码\n\n");
if(ptr==NULL){
printf("霍夫曼树是空的!
\n");
exit(0);
}
else{
while(ptr->lchild&&ptr->rchild&&ptr->mark==0){
while(ptr->lchild&&ptr->lchild->mark==0){
code[index++]='0';
ptr=ptr->lchild;
if(!
ptr->lchild&&!
ptr->rchild){
ptr->mark=1;
code[index]='\0';
printf("\tw[%c]=%d\t\t\t",ptr->ch,ptr->weight);
for(index=0;code[index]!
='\0';index++)
printf("%c",code[index]);
printf("\n");
ptr=tree;
index=0;
}
}
if(ptr->rchild&&ptr->rchild->mark==0){
ptr=ptr->rchild;
code[index++]='1';
}
if(!
ptr->lchild&&!
ptr->rchild){
ptr->mark=1;
code[index++]='\0';
printf("\tw[%c]=%d\t\t\t",ptr->ch,ptr->weight);
for(index=0;code[index]!
='\0';index++)
printf("%c",code[index]);
printf("\n");
ptr=tree;
index=0;
}
if(ptr->lchild->mark==1&&ptr->rchild->mark==1)
{
ptr->mark=1;
ptr=tree;
index=0;
}
}
}
printf("\n");
free(code);
}
/***********************哈夫曼解码函数************************/
/*解码*/
voiddecode(linktreetree,charcode[])
{
inti=0,j=0;
char*char0_1;
linktreeptr=tree;
char0_1=(char*)malloc(10*sizeof(char));/*此数组用于统计输入的0、1序列*/
printf("霍夫曼编码-----相应字符\n\n");
for(j=0,ptr=tree;code[i]!
='\0'&&ptr->lchild&&ptr->rchild;j=0,ptr=tree){
for(j=0;code[i]!
='\0'&&ptr->lchild&&ptr->rchild;j++,i++){
if(code[i]=='0'){
ptr=ptr->lchild;
char0_1[j]='0';
}
if(code[i]=='1'){
ptr=ptr->rchild;
char0_1[j]='1';
}
}
if(!
ptr->lchild&&!
ptr->rchild){
char0_1[j]='\0';
for(j=0;char0_1[j]!
='\0';j++)
printf("%c",char0_1[j]);
printf("\t\t%c\n",ptr->ch);
}
if(code[i]=='\0'&&ptr->lchild&&ptr->rchild){
char0_1[j]='\0';
printf("没有与最后的几个0、1序列:
%s相匹配的字符!
\n",char0_1);
return;
}
}
free(char0_1);
}
/********************释放哈夫曼空间函数************************/
/*释放霍夫曼树所占用的空间*/
voiddeletenode(linktreetree)
{
linktreeptr=tree;
if(ptr){
deletenode(ptr->lchild);
deletenode(ptr->rchild);
free(ptr);
}
}
/***********************主函数*************************/
voidmain()
{
charorz,back,flag=1;
charcharacter[MAXLEN],code[MAXLEN];
linktreetemp,ht,htree,ptr=NULL;
while(flag)//菜单函数,当flag为0时跳出循环
{
printf("\n");
printf("**************************************");
printf("\n**A-------------------编码**");
printf("