数据结构实验报告.docx
- 文档编号:24047933
- 上传时间:2023-05-23
- 格式:DOCX
- 页数:25
- 大小:249.31KB
数据结构实验报告.docx
《数据结构实验报告.docx》由会员分享,可在线阅读,更多相关《数据结构实验报告.docx(25页珍藏版)》请在冰豆网上搜索。
数据结构实验报告
编号:
江西理工大学
数据结构课程设计报告
班级:
学号:
姓名:
时间:
指导教师:
第一章需求分析
1.1实验内容概述
◆纸牌游戏
编号为1-52张牌,正面向上,从第2张开始,以2为基数,是2的倍数的牌翻一次,直到最后一张牌;然后,从第3张开始,以3为基数,是3的倍数的牌翻一次,直到最后一张牌;然后…从第4张开始,以4为基数,是4的倍数的牌翻一次,直到最后一张牌;...再依次5的倍数的牌翻一次,6的,7的直到以52为基数的翻过,输出:
这时正面向上的牌有哪些?
要求:
用数组、链表结构实现,采用递归方法。
◆哈夫曼编码
设计出下面字符表的哈夫曼编码对应的二叉树,并输出每个字符的哈夫曼编码。
字符
m
n
o
p
q
r
出现频率(%)
13
44
12
17
9
5
1.2实验目的概述
◆纸牌游戏
①了解线性表的特性,以及它们在实际问题中的应用。
②掌握顺序表和链表的实现方法,以及它们的基本操作。
③掌握线性表的链式存储结构——单链表的定义及其C语言实现。
④掌握线性表在链式存储结构——单链表中的各种基本操作。
⑤通过用链表编程实现问题的解决,提高自身的问题解决能力。
◆哈夫曼编码
以字符的频度为权值,建立哈夫曼树,求哈夫曼编码。
根据字符及权值得到其相应的编码。
第二章概要设计
2.1抽象数据类型定义
◆纸牌游戏
structnode//定义结点
{intdata;
intkey;//定义标志位
structnode*next;
}
◆哈夫曼编码
typedefstruct
{intweight;/*结点的权值*/
intlchild,rchild,parent;/*左、右孩子及双亲的下标*/
}htnode;
typedefhtnodehuffmantree[m+1];/*huffmantree是结构数组类型,其0号单元不用,存储哈夫曼树*/
typedefstruct
{charch;/*存储字符*/
charcode[n+1];/*存放编码位串*/
}codenode;
typedefcodenodehuffmancode[n+1];/*huffmancode是结构数组类型,其0号单元不用,存储哈夫曼编码*/
2.2程序流程图
◆纸牌游戏
◆哈夫曼编码
2.3链表分析
①初始化头结点正面朝上
②初始化所有牌正面朝上
③循环完后递归
第三章
详细设计
3.1定义关键步骤
◆纸牌游戏
structnode*create()//定义链表建立函数create()
{structnode*p,*head,*s;//其返回值为结构指针
inti;
head=NULL;//初始化头指针
p=(structnode*)malloc(sizeof(*p));//生成P结点
if(p==NULL)
{printf("Memoryistoosmall!
\n");
}
head=p;
head->data=1;
head->key=1;
head->next=NULL;
for(i=2;i<=52;i++)//建立结点的链表
{s=(structnode*)malloc(sizeof(*p));
s->data=i;
s->key=1;//初始化所有牌都是正面朝上
p->next=s;
p=s;
}
p->next=NULL;
return(head);
}
◆哈夫曼编码
#include
#include
#include
#include
#definen6/*叶子数目根据需要设定*/
#definem2*n-1/*Huffman树中结点总数*/
3.2定义关键函数
◆纸牌游戏
voidfanpai(structnode*p)//翻牌算法
{structnode*p1,*p2;
p1=p;
if(p1!
=NULL){
fanpai(p1->next);/*递归,一直调用p1但不执行,直到p1=52,然后p2从52开始、51开始、50开始......*/
}//先执行外循环,直到p1->next=null,在执行内循环,即翻牌
for(p2=p1;p2!
=NULL;p2=p2->next)//p1从2开始固定,然后p2一直往后走
{
if(p2->data%p1->data==0)//是p1的倍数则翻牌
{
if(p2->key==0)
p2->key=1;
else
p2->key=0;
}
}
}
◆哈夫曼编码
1)初始化函数:
voidinithuffmantree(huffmantreeht)
{inti;
for(i=0;i<=m;i++)
{ht[i].weight=0;
ht[i].lchild=ht[i].rchild=ht[i].parent=0;
}
}
2)输入权值函数:
voidinputweight(huffmantreeht)
{inti;
for(i=1;i<=n;i++)
{
printf("……请输入第[%d]个权值:
",i);
scanf("%d",&ht[i].weight);
}
printf("\n");
}
3)选权值最小序号函数:
voidselectmin(huffmantreeht,inti,int*p1,int*p2)
{intj,min1,min2;/*min1,min2分别是最小权值和次小权值*/
min1=min2=32767;
*p1=*p2=0;
for(j=1;j<=i;j++)
{if(ht[j].parent==0)/*j为根结点*/
if(ht[j].weight { if(min1! =32767){min2=min1;*p2=*p1;} min1=ht[j].weight;*p1=j; } else if(ht[j].weight {min2=ht[j].weight;*p2=j;} } } 4)构造哈夫曼树函数 voidcreatehuffmantree(huffmantreeht) { inti,p1,p2; inithuffmantree(ht);/*将ht初始化*/ inputweight(ht);/*输入叶子权值至ht[1..n]的weight域*/ for(i=n+1;i<=m;i++)/*共进行n-1次合并,新结点依次存于ht[i]中*/ {selectmin(ht,i-1,&p1,&p2);/*在ht[1..i-1]中选择两个权值最小的根结点,其序号分别为p1和p2*/ ht[p1].parent=ht[p2].parent=i; ht[i].lchild=p1;/*最小权值的根结点是新结点的左孩子*/ ht[i].rchild=p2;/*次小权值的根结点是新结点的右孩子*/ ht[i].weight=ht[p1].weight+ht[p2].weight; } } 5)编码函数 voidhuffmancodes(huffmantreeht,huffmancodehcd) { intc,p,i;/*c和p分别指示ht中孩子和双亲的位置*/ charcd[n+1];/*临时存放编码*/ intstart;/*指示编码在cd中的起始位置*/ cd[n]='\0'; getchar();/*编码结束符*/ printf("2.……请依次输入字符……: "); for(i=1;i<=n;i++)/*依次求叶子ht[i]的编码*/ {hcd[i].ch=getchar();/*读入叶子ht[i]对应的字符*/ start=n;/*编码起始位置的初值*/ c=i;/*从叶子ht[i]开始上溯*/ while((p=ht[c].parent)! =0)/*直至上溯到ht[c]是树根为止*/ {cd[--start]=(ht[p].lchild==c)? '0': '1';/*若ht[c]是ht[p]的左孩子,则生成代码0,否则生成代码1*/ c=p;/*继续上溯*/ } strcpy(hcd[i].code,&cd[start]);/*复制编码位串*/ } printf("\n"); printf("3.………哈夫曼编码结果为: ……\n"); printf("\n"); for(i=1;i<=n;i++) printf("……第[%d]个符[%c]的编码为: %s\n",i,hcd[i].ch,hcd[i].code); } 3.3主函数 ◆纸牌游戏 voidmain() {structnode*head,*np; head=create(); if(head==NULL) printf("链接错误! \n"); fanpai(head);//调用翻牌算法开始翻牌 printf("\n最后正面向上的牌有"); for(np=head;np! =NULL;np=np->next)//输出翻牌完成后的结果 {if(np->key==0) printf("%4d",np->data); } printf("\n"); } ◆哈夫曼编码 voidmain() {huffmantreet; huffmancodeh; printf("|^^^^^^^^^^^^^^^^^^^^^^^^^^^*########################*^^^^^^^^^^^^^^^^^^^|\n"); printf("|^^^^^^^^^^^^^^^^^^^^^^^^^^^*欢迎使用哈弗曼编码系统! *^^^^^^^^^^^^^^^^^^^|\n"); printf("|^^^^^^^^^^^^^^^^^^^^^^^^^^^*########################*^^^^^^^^^^^^^^^^^^^|\n"); printf("\n"); printf("1.…………请输入%d个权值: ……\n",n); printf("\n"); createhuffmantree(t);/*构造huffman树*/ huffmancodes(t,h);/*构造huffman编码*/ } 第四章调试分析 4.1问题讨论 ◆纸牌游戏 之前的代码: voidfanpai(structnode*p) {structnode*p1,*p2; for(p1=p->next;p1! =NULL;p1=p1->next) {for(p2=p1;p2! =NULL;p2=p2->next) {if(p2->data%p1->data==0) {if(p2->key=1; else p2->key=0; } } } } 由于没有用到递归,不满足实验要求,所以改为以下代码 voidfanpai(structnode*p) {structnode*p1,*p2; p1=p; if(p1! =NULL){ fanpai(p1->next); } for(p2=p1;p2! =NULL;p2=p2->next) { if(p2->data%p1->data==0) { if(p2->key==0) p2->key=1; else p2->key=0; } } } ◆哈夫曼编码 4.2经验与体会 在编写程序时应该用规范化的格式输入源程序,同时注意不要忘了编写头文件#include 在调用指针时应先将其初始化,如果没有初始化指针就调用它,这样很不安全,虽然你有时可以运行,却有了不安定的因素。 如: int*data;可以成定义: intdata[52];这里的data是一个常量地址,也是一个数组名,因此不用担心它没有被初始化。 4.3测试结果 ◆纸牌游戏 ◆哈夫曼编码 第五章总结分析 通过这次的数据结构课程设计,我明显感觉到自己在很多方面的不足,但问题总是要解决的,必须找出问题然后将其一一解除。 所以在整个过程中,我不断加深了对数据结构的理解与一些程序写书时要注意的事项,也让我对这门课程有了进一步的了解和认识。 完成一个课程设计要注意很多方面,无论是格式、书写的内容还是要表达的思想,所以我们必须严格要求自己。 本次课程设计涉及了很多知识,由于往日学得不扎实,对某些问题仍然存在疑惑,我查阅了相关书籍,以便将疑难问题解决,同时更加进一步的掌握相关知识。 此次的课程设计不仅让我深刻体会到了学习这门课程的重要性与必要性,也让我懂得了学习是思考一个的过程,我们应该主动去思考学到的知识以及学到后怎么去运用,而不是一味地被动地接受。 数据结构及其算法在解决现实生活中的常见问题和书写软件设计方面上都有着重要的意义,我们应该好好掌握它的相关知识,在以后的学习过程中,更多的去学会如何运用知识。 第六章参考文献 [1]刘振鹏张晓莉郝杰.数据结构.北京: 中国铁道出版社.2005 [2]谭浩强.C语言程序设计(第二版).北京: 清华大学出版社.2008 [3]严蔚敏吴伟民.数据结构(C语言版).北京: 清华大学出版社.2010 [4]黄国瑜叶乃菁.数据结构(C语言版).北京: 清华大学出版社.2002 [5]朱站立.数据结构(第三版).西安: 西安交通大学出版社.2004 附录源程序 ◆纸牌游戏 #include #include #include structnode//定义结点 {intdata;//定义数据域,即牌的序号 intkey;//标志key为1表示正面朝上key为0表示反面朝上 structnode*next; }; structnode*create()//定义链表建立函数create() {structnode*p,*head,*s;//其返回值为结构指针 inti;//牌的序号,1-52 head=NULL;//初始化头指针 p=(structnode*)malloc(sizeof(*p));//生成P结点 if(p==NULL) {printf("Memoryistoosmall! \n"); } head=p; head->data=1; //第一张牌 head->key=1; head->next=NULL; for(i=2;i<=52;i++)//建立结点的链表 {s=(structnode*)malloc(sizeof(*p));//s结点是临时的,p结点跟着s结点走,直到52 s->data=i;//牌号,1-52 s->key=1;//初始化所有牌都是正面朝上 p->next=s; p=s; } p->next=NULL; return(head); } voidfanpai(structnode*p)//翻牌算法 {structnode*p1,*p2; p1=p; if(p1! =NULL){ fanpai(p1->next);//递归,一直调用p1但不执行,直到p1=52,然后p2从52开始、51开始、50开始。 。 。 }//先执行外循环,直到p1->next=null,在执行内循环,即翻牌 for(p2=p1;p2! =NULL;p2=p2->next)//p1从2开始固定,然后p2一直往后走 { if(p2->data%p1->data==0)//是p1的倍数则翻牌 { if(p2->key==0) p2->key=1; else p2->key=0; } } } voidmain() {structnode*head,*np; head=create(); if(head==NULL) printf("链接错误! \n"); fanpai(head);//调用翻牌算法开始翻牌 printf("\n最后正面向上的牌有"); for(np=head;np! =NULL;np=np->next)//输出翻牌完成后的结果 {if(np->key==0) printf("%4d",np->data); } printf("\n"); } ◆哈夫曼编码 #include #include #include #include /*Huffman树的存储结构*/ #definen6/*叶子数目根据需要设定*/ #definem2*n-1/*Huffman树中结点总数*/ /*Huffman树的存储结构*/ typedefstruct/*结构体定义*/ {intweight;/*结点的权值*/ intlchild,rchild,parent;/*左、右孩子及双亲的下标*/ }htnode;/*哈夫曼树结点类型*/ typedefhtnodehuffmantree[m+1];/*huffmantree是结构数组类型,其0号单元不用,存储哈夫曼树*/ typedefstruct {charch;/*存储字符*/ charcode[n+1];/*存放编码位串*/ }codenode;/*编码结点类型*/ typedefcodenodehuffmancode[n+1];/*huffmancode是结构数组类型,其0号单元不用,存储哈夫曼编码*/ voidinithuffmantree(huffmantreeht)/*初始化哈夫曼树函数inithuffmantree()*/ {inti; for(i=0;i<=m;i++) {ht[i].weight=0; ht[i].lchild=ht[i].rchild=ht[i].parent=0; } } voidinputweight(huffmantreeht)/*输入权值函数*/ {inti; for(i=1;i<=n;i++) { printf("……请输入第[%d]个权值: ",i); scanf("%d",&ht[i].weight); } printf("\n"); } voidselectmin(huffmantreeht,inti,int*p1,int*p2) /*在ht[1..i]中选两个权值最小的根结点,其序号为*p1和*p2,*p1中放权值最小的根结点的序号,*p2中放权值次小的根结点的序号*/ {intj,min1,min2;/*min1,min2分别是最小权值和次小权值*/ min1=min2=32767; *p1=*p2=0; for(j=1;j<=i;j++) {if(ht[j].parent==0)/*j为根结点*/ if(ht[j].weight { if(min1! =32767){min2=min1;*p2=*p1;} min1=ht[j].weight;*p1=j; } else if(ht[j].weight {min2=ht[j].weight;*p2=j;} } } voidcreatehuffmantree(huffmantreeht)/*构造huffman树,ht[m]为其根结点*/ { inti,p1,p2; inithuffmantree(ht);/*将ht初始化*/ inputweight(ht);/*输入叶子权值至ht[1..n]的weight域*/ for(i=n+1;i<=m;i++)/*共进行n-1次合并,新结点依次存于ht[i]中*/ {selectmin(ht,i-1,&p1,&p2);/*在ht[1..i-1]中选择两个权值最小的根结点,其序号分别为p1和p2*/ ht[p1].parent=ht[p2].parent=i; ht[i].lchild=p1;/*最小权值的根结点是新结点的左孩子*/ ht[i].rchild=p2;/*次小权值的根结点是新结点的右孩子*/ ht[i].weight=ht[p1].weight+ht[p2].weight; } } voidhuffmancodes(huffmantreeht,huffmancodehcd)/*根据huffman树ht求huffman编码*/ { intc,p,i;/*c和p分别指示ht中孩子和双亲的位置*/ charcd[n+1];/*临时存放编码*/ intstart;/*指示编码在cd中的起始位置*/ cd[n]='\0'; getchar();/*编码结束符*/ printf("2.……请依次输入字符……: "); for(i=1;i<=n;i++)/*依次求叶子ht[i]的编码*/ {hcd[i].ch=getchar();/*读入叶子ht[i]对应的字符*/ start=n;/*编码起始位置的初值*/ c=i;/*从叶子ht[i]开始上溯*/ while((p=ht[c].parent)! =0)/*直至上溯到ht[c]是树根为止*/ {cd[--start]=(ht[p].lchild==c)? '0': '1';/*若ht[c]是ht[p]的左孩子,则生成代码0,否则生成代码1*/ c=p;/*继续上溯*/ } strcpy(hcd[i].code,&cd[start]);/*复
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 数据结构 实验 报告