数据结构 课程设计小样儿.docx
《数据结构 课程设计小样儿.docx》由会员分享,可在线阅读,更多相关《数据结构 课程设计小样儿.docx(24页珍藏版)》请在冰豆网上搜索。
数据结构课程设计小样儿
摘要
《数据结构》主要介绍一些最常用的数据结构,阐明各种数据结构内在的逻辑关系,讨论其在计算机中的存储表示,以及在其上进行各种运算时的实现算法,并对算法的效率进行简单的分析和讨论。
数据结构是介于数学、计算机软件和计算机硬件之间的一门计算机专业的核心课程,它是计算机程序设计、数据库、操作系统、编译原理及人工智能等的重要基础,广泛的应用于信息学、系统工程等各种领域。
算法与数据结构旨在分析研究计算机加工的数据对象的特性,以便选择适当的数据结构和存储结构,从而使建立在其上的解决问题的算法达到最优。
本次课程设计主要应用基本的数据结构知识,顺序表实现稀疏矩阵的快速转置和乘法、赫夫曼编码,更深刻的了解数据结构的实际意义,实现课本算法。
关键词:
赫夫曼编码,稀疏矩阵,快速转置,矩阵乘法
目录
一、稀疏矩阵的快速转置和乘法1
1、程序设计要求1
2、存储结构1
3、主要算法设计2
4、流程图4
5、源代码:
5
6、运行结果11
二、赫夫曼编码12
1、程序设计要求12
2、存储结构:
12
3、主要算法设计:
13
4、流程图14
5、源程序15
6、运行结果19
心得体会19
参考文献20
一、稀疏矩阵的快速转置和乘法
1、程序设计要求
1.以“带行逻辑链接信息”的三元组顺序表表示稀疏矩阵,实现矩阵的转置和两个矩阵相乘的运算
2.首先应输入矩阵的行数和列数,并判别给出的两个矩阵的行、列数对于所要求作的运算是否相匹配。
可设矩阵的行数和列数均不超过20。
3.本程序中,按提示入相应的数据,由用户在键盘上输入演示程序中规定的输入数据。
这里输入的数据值为整型。
2、存储结构
用三元组表示稀疏矩阵各元素:
row
col
value
三元组的结构图
用顺序存储结构表示三元组表:
Row
Col
Value
顺序存储结构图
稀疏矩阵的三元组顺序表存储结构:
typedefstruct{
inti,j;/*行下标,列下标*/
ElemTypee;/*非零元值*/
}Triple;
typedefstruct{
Tripledata[MAXSIZE+1];/*零元三元组表,data[0]未用*/
intrpos[MAXRC+1];
intmu,nu,tu;/*阵的行数、列数和非零元个数*/
}TSMatrix;
3、主要算法设计
抽象数据类型稀疏矩阵的定义如下:
ADTSparseMatrix{
数据对象:
D={aij|i=1,2,3……..,m;j=1,2,3…….,n;
Aij属于Elemset,m和n分别称为矩阵的行数和列数}
数据关系:
R={Row,Col}
Row={|1<=i<=m,1<=j<=n-1}
Col={|1<=i<=m-1,1<=j<=n}
基本操作;
CreateSMatrix(&M);
操作结果:
创建稀疏矩阵M;
PrintSMatrix(M);
初始条件:
稀疏矩阵M存在。
操作结果:
输出稀疏矩阵M;
TransposeSmatrix(M,N) ;
初始条件:
稀疏矩阵M存在。
操作结果:
输出稀疏矩阵N
MultSMatrix(M,N,&Q);
初始条件:
稀疏矩阵M的行数等于N的列数。
操作结果:
求稀疏矩阵的和Q=M*N.
}ADTSparseMatrix
(1)、快速转置算法:
StatusTransposeSMatrix(TSMatrixM,TSMatrix&T)
{
T.mu=M.nu;T.nu=M.mu;T.tu=M.tu;
for(p=1;p<=M.nu;++p)num[p]=0;
for(q=1;q<=M.tu;++q)++num[M.data[q].j];
cpot[1]=1;
for(p=2;p<=M.nu;++p)cpot[p]=cpot[p-1]+num[p-1];
for(q=1;q<=M.tu;++q)
{p=M.data[q].j;
k=cpot[p];
T.data[k].i=M.data[q].j;
T.data[k].j=M.data[q].i;
T.data[k].e=M.data[q].e;
++cpot[p];
}
returnOK;
}
算法时间复杂度为:
O(mu+nu)
(2)、矩阵乘法算法:
StatusMultSMatrix(TSMatrixM,TSMatrixN,TSMatrix&Q)
{
if(M.tu==0||N.tu==0)returnERROR;
Q.mu=M.mu;
Q.nu=N.nu;
Q.tu=0;
for(arow=1;arow<=M.mu;++arow)
{for(ccol=1;ccol<=N.nu;ccol++)
ctemp[ccol]=0;
if(arowtp=M.rpos[arow+1];
elsetp=M.tu+1;
for(p=M.rpos[arow];p{brow=M.data[p].j;
if(browt=N.rpos[brow+1];
elset=N.tu+1;
for(q=N.rpos[brow];q{ccol=N.data[q].j;
ctemp[ccol]+=M.data[p].e*N.data[q].e;
}
}
for(ccol=1;ccol<=Q.nu;++ccol)
{if(ctemp[ccol]!
=0)
{Q.tu++;
if(Q.tu>MAXSIZE)returnERROR;
Q.data[Q.tu].i=arow;
Q.data[Q.tu].j=ccol;
Q.data[Q.tu].e=ctemp[ccol];}
}
}
returnOK;
}
算法时间复杂度为:
O(mu*nu)
4、流程图
主程序流程图
5、源代码:
#include
#include
#defineTRUE1
#defineFALSE0
#defineOK1
#defineERROR0
#defineMAXSIZE20
#defineMAXRC10
typedefintStatus;
typedefintElemType;
typedefstruct{
inti,j;/*行下标,列下标*/
ElemTypee;/*非零元值*/
}Triple;
typedefstruct{
Tripledata[MAXSIZE+1];/*零元三元组表,data[0]未用*/
intrpos[MAXRC+1];
intmu,nu,tu;/*阵的行数、列数和非零元个数*/
}TSMatrix;
StatusCreateSMatrix(TSMatrix&M)/*创建一个稀疏矩阵*/
{
intp=1,a,b,c;
printf("请输入稀疏矩阵的行数,列数,非零元数(请小于20个,用空格隔开各数据):
");
scanf("%d%d%d",&M.mu,&M.nu,&M.tu);
if(M.tu>MAXSIZE||M.tu<=0||M.tu>M.mu*M.nu)
{printf("-----出错啦,非零元个数超过最大值!
!
\n");returnERROR;}
while(p<=M.tu)
{printf("请输入第%d个非零元素的行,列,元素值(用空格隔开):
",p);
scanf("%d%d%d",&a,&b,&c);
M.data[0].i=0;M.data[0].j=0;
if(a<=M.mu&&b<=M.nu&&c!
=0)
{if(a>M.data[p-1].i||(a==M.data[p-1].i&&b>M.data[p-1].j))
{M.data[p].i=a;M.data[p].j=b;M.data[p].e=c;p++;}
elseprintf("-----出错啦,请从行到列,从小到大输入!
!
\n");
}
elseprintf("-----出错啦,所输入数据超出范围!
!
\n");
if(a==M.mu&&b==M.nu&&p<=M.tu){printf("-----出错啦,输入顺序有误,请认真核查,从头输入!
!
\n");p=1;}
}
printf("-----输入成功!
!
\n");
returnOK;
}
StatusPrintMatrix(TSMatrixM)/*输出一个矩阵*/
{inti,j,p=1;
if(M.tu==0){printf("-----找不到此矩阵或为空矩阵!
!
\n");returnERROR;}
printf("---%d行%d列%d个非零元素---\n以阵列方式输出为:
\n",M.mu,M.nu,M.tu);
for(i=1;i<=M.mu;i++)
{for(j=1;j{if(i==M.data[p].i&&j==M.data[p].j)
{printf("%d",M.data[p].e);p++;}
elseprintf("%d",0);
}
if(i==M.data[p].i&&j==M.data[p].j)
{printf("%d\n",M.data[p].e);p++;}
elseprintf("%d\n",0);
}
returnOK;
}
StatusMultSMatrix(TSMatrixM,TSMatrixN,TSMatrix&Q)
{intarow,brow,p,q,ccol,ctemp[MAXRC+1],t,tp,k=1;
if(M.tu==0||N.tu==0){
printf("-----找不到所需矩阵!
!
\n");
returnERROR;}
if(M.nu!
=N.mu){printf("-----此矩阵不能被运算,请核查行列数!
!
\n");returnERROR;}
for(p=1;p<=M.tu;p++)/*为M.rpos[]赋值*/
{if(M.data[p].i==k)
{M.rpos[k]=p;
k++;}
elseif(M.data[p].i>k)
{M.rpos[k]=p--;
k++;}
}
for(;k<=M.mu;k++)M.rpos[k]=M.tu;
k=1;
for(q=1;q<=N.tu;q++)/*为N.rpos[]赋值*/
{if(N.data[q].i==k)
{N.rpos[k]=q;k++;}
elseif(N.data[q].i>k)
{N.rpos[k]=p--;k++;}
}
for(;k<=N.mu;k++)N.rpos[k]=N.tu;
Q.mu=M.mu;/*初始化Q*/
Q.nu=N.nu;
Q.tu=0;
for(arow=1;arow<=M.mu;++arow)
{for(ccol=1;ccol<=N.nu;ccol++)
ctemp[ccol]=0;
if(arowtp=M.rpos[arow+1];
elsetp=M.tu+1;
for(p=M.rpos[arow];p{brow=M.data[p].j;
if(browt=N.rpos[brow+1];
elset=N.tu+1;
for(q=N.rpos[brow];q{ccol=N.data[q].j;
ctemp[ccol]+=M.data[p].e*N.data[q].e;
}
}
for(ccol=1;ccol<=Q.nu;++ccol)/*将数组的值压缩储存到Q*/
{if(ctemp[ccol]!
=0)
{Q.tu++;
if(Q.tu>MAXSIZE){printf("-----出错啦,非零元个数超出最大值!
!
\n");returnERROR;}
Q.data[Q.tu].i=arow;
Q.data[Q.tu].j=ccol;
Q.data[Q.tu].e=ctemp[ccol];}
}
}
printf("-----运算成功!
!
\n");
returnOK;
}
StatusFastTransposeSMatrix(TSMatrixM,TSMatrix&T)/*求快速稀疏矩阵M的转置矩阵T*/
{
intp,q,k=1;
intcpot[MAXSIZE],num[MAXSIZE];
if(M.tu==0){printf("-----找不到所需矩阵!
!
\n");returnERROR;}
T.mu=M.nu;T.nu=M.mu;T.tu=M.tu;
for(p=1;p<=M.nu;++p)num[p]=0;
for(q=1;q<=M.tu;++q)++num[M.data[q].j];
cpot[1]=1;
for(p=2;p<=M.nu;++p)cpot[p]=cpot[p-1]+num[p-1];
for(q=1;q<=M.tu;++q)
{p=M.data[q].j;
k=cpot[p];
T.data[k].i=M.data[q].j;
T.data[k].j=M.data[q].i;
T.data[k].e=M.data[q].e;
++cpot[p];
}
printf("-----转置成功!
!
\n");
returnOK;
}
voidmain()
{
intselect;
TSMatrixA,B,C;
A.tu=0;B.tu=0;C.tu=0;
printf("0.退出程序\n");
printf("1.创建矩阵A\n");
printf("2.输出矩阵A\n");
printf("3.输出矩阵B\n");
printf("4.输出矩阵C\n");
printf("5.转置矩阵A->B\n");
printf("6.矩阵相乘A*B=C\n");
printf("\n");
while
(1)
{
printf("请选择:
");
scanf("%d",&select);
if(select==0)break;
switch(select){
case1:
CreateSMatrix(A);
break;
case2:
PrintMatrix(A);
break;
case3:
PrintMatrix(B);
break;
case4:
PrintMatrix(C);
break;
case5:
FastTransposeSMatrix(A,B);
break;
case6:
MultSMatrix(A,B,C);
break;
default:
printf("输入错误,请认真核查!
!
\n");
break;
}
}
}
6、运行结果
二、赫夫曼编码
1、程序设计要求
设计一个赫夫曼编码系统,具有一下功能:
1、输入字符和权值,构造赫夫曼树
2、求出各个字符的赫夫曼编码
2、存储结构:
Chrweightparentlchildrchild
赫夫曼树顺序存储结构图
1
2
3
4
5
赫夫曼编码存储结构图
赫夫曼树和赫夫曼编码的存储表示:
typedefstruct{
charch;
intweight;
intparent,lchild,rchild;
}htnode,*hfmtree;
typedefchar**hfmcode;
3、主要算法设计:
赫夫曼树的建立和编码求解
voidhfmcoding(hfmtree&HT,hfmcode&HC,intn){
if(n<=1)return;
m=2*n-1;
HT=(hfmtree)malloc((m+1)*sizeof(htnode));
for(i=1;i<=n;++i){
printf("请输入第%d字符信息和权值:
",i);
scanf("%c%d",&z,&w);
while(getchar()!
='\n')
{continue;}
HT[i].ch=z;
HT[i].weight=w;
HT[i].parent=0;
HT[i].lchild=0;
HT[i].rchild=0;
}
for(;i<=m;++i)//初始化其余的结点
{
HT[i].ch='0';
HT[i].weight=0;
HT[i].parent=0;
HT[i].lchild=0;
HT[i].rchild=0;
}
for(i=n+1;i<=m;++i)//建立赫夫曼树
{
Select(HT,i-1,&p1,&p2);
HT[p1].parent=i;HT[p2].parent=i;
HT[i].lchild=p1;HT[i].rchild=p2;
HT[i].weight=HT[p1].weight+HT[p2].weight;
}
HC=(hfmcode)malloc((n+1)*sizeof(char*));
cd=(char*)malloc(n*sizeof(char));
cd[n-1]='\0';
for(i=1;i<=n;++i)//给n个字符编码
{
start=n-1;
for(c=i,f=HT[i].parent;f!
=0;c=f,f=HT[f].parent)
{
if(HT[f].lchild==c)
{cd[--start]='0';}
else
{cd[--start]='1';}
}
HC[i]=(char*)malloc((n-start)*sizeof(char));
strcpy(HC[i],&cd[start]);
}
free(cd);
}
时间复杂度为O(n*log2n)
4、流程图
主函数流程图
5、源程序
#include
#include
#include
#include
#include
typedefstruct{
charch;
intweight;
intparent,lchild,rchild;
}htnode,*hfmtree;
typedefchar**hfmcode;
voidSelect(hfmtree&HT,inta,int*p1,int*p2)//Select函数
{
inti,j,x,y;
for(j=1;j<=a;++j){
if(HT[j].parent==0){
x=j;
break;}
}
for(i=j+1;i<=a;++i){
if(HT[i].weightx=i;//选出最小的节点
}
}
for(j=1;j<=a;++j){
if(HT[j].parent==0&&x!
=j)
{y=j;
break;}
}
for(i=j+1;i<=a;++i)
{
if(HT[i].weight=i)
{y=i;}//选出次小的节点
}
if(x>y){
*p1=y;
*p2=x;
}
else
{*p1=x;
*p2=y;}
}
voidhfmcoding(hfmtree&HT,hfmcode&HC,intn)/{
inti,start,c,f,m,w;
intp1,p2;
char*cd,z;
if(n<=1){
return;
}
m=2*n-1;
HT=(hfmtree)malloc((m+1)*sizeof(htnode));
for(i=1;i<=n;++i)//初始化n个叶子结点
{
printf("请输入第%d字符信息和权值:
",i);
scanf("%c%d",&z,&w);
while(getchar()!
='\n')
{continue;}
HT[i].ch=z;
HT[i].weight=w;
HT[i].parent=0;
HT[i].lchild=0;
HT[i].rchild=0;
}
for(;i<=m;++i)//初始化其余的结点
{
HT[i].ch='0';
HT[i].weight=0;
HT[i].parent=0;
HT[i].lchild=0;
HT[i].rchild=0;
}
for(i=n+1;i<=m;++i)//建立赫夫曼树
{
Select(HT,i-1,&p1,&p2);
HT[p1].parent=i;HT[p2].parent=i;
HT[i].lchild=p1;HT[i].rchild=p2;
HT[i].weight=HT[p1].weight+HT[p2].weight;
}
HC=(hfmcode)malloc((n+1)*sizeof(char*));
cd=(char*)malloc(n*sizeof(char));
cd[n-1]='\0';
for(i=1;i<=n;++i)//给n个字符编码
{
start=n-1;
for(c=i,f=HT[i].parent;f!
=0;c=f,f=HT[f].parent)
{
if(HT[f].lchild==c)
{cd[--start]='0';}
else
{cd[--start]='1';}
}
HC[i]=(char*)malloc((n-start)*sizeof(ch