数据结构与算法.docx
《数据结构与算法.docx》由会员分享,可在线阅读,更多相关《数据结构与算法.docx(26页珍藏版)》请在冰豆网上搜索。
数据结构与算法
数据结构与算法 实验报告
实验一线性表及其应用
一、实验目的和要求
1、掌握线性表的插入、删除、查找等基本操作设计与实现
2、学习利用线性表提供的接口去求解实际问题
3、熟悉线性表的的存储方法
二、实验内容和原理
1、实验内容:
设计一个一元多项式的简单计算器,其基本功能有①输入并建立多项式;②输出多项式;③多项式相加。
可利用单链表或单循环链表实现之。
2、实验原理:
以线性表来描述一元多项式,存储结构采用单链表,每个结点存储的多项式中某一项的系数和指数,建立单链表时指数高的结点列于指数低的结点之后,即线性表的元素按指数递增有序排列。
三、实验环境
VisualC++6.0及PC机
四、算法描述及实验步骤
no
五、调试过程
在调试的过程中,出现了一些错误,通过不断调试最终通过
六、实验结果
七、总结
通过这次的实验,我认识到了多项式的运算问题宜考虑采用链式存储结构即单链表实现,而不适合用顺序表结构。
附录:
创建多项式:
mulpoly*creatpoly()
{mulpoly*head,*r,*s;
intm,n;
head=(mulpoly*)malloc(sizeof(mulpoly));
printf("\ninputcoefandexp:
\n");
scanf("%d%d",&n,&m);
r=head;
while(n!
=0)
{s=(mulpoly*)malloc(sizeof(mulpoly));
s->coef=n;
s->exp=m;
r->next=s;
r=s;
scanf("%d%d",&n,&m);
}
r->next=NULL;
head=head->next;
return(head);
}
多项式相加:
mulpoly*polyadd(mulpoly*ha,mulpoly*hb)
{mulpoly*hc,*p,*q,*s,*r;
intx;p=ha;q=hb;
hc=(mulpoly*)malloc(sizeof(mulpoly));
s=hc;
while((p!
=NULL)&&(q!
=NULL))
if(p->exp==q->exp)
{
x=p->coef+q->coef;
if(x!
=0)
{r=(mulpoly*)malloc(sizeof(mulpoly));
r->exp=p->exp;
r->coef=x;
s->next=r;
s=r;
}
p=p->next;
q=q->next;
}
else
if(p->expexp)
{r=(mulpoly*)malloc(sizeof(mulpoly));
r->coef=q->coef;
r->exp=q->exp;
s->next=r;
s=r;
q=q->next;
}
else
{r=(mulpoly*)malloc(sizeof(mulpoly));
r->exp=p->exp;
r->coef=p->coef;
s->next=r;
s=r;
p=p->next;
}
while(p!
=NULL)
{r=(mulpoly*)malloc(sizeof(mulpoly));
r->exp=p->exp;
r->coef=p->coef;
s->next=r;
s=r;
p=p->next;
}
while(q!
=NULL)
{r=(mulpoly*)malloc(sizeof(mulpoly));
r->exp=q->exp;
r->coef=q->coef;
s->next=r;
s=r;
q=q->next;
}
s->next=NULL;
r=hc;
hc=hc->next;
free(r);
return(hc);
}
多项式相减:
mulpoly*polysubtr(mulpoly*ha,mulpoly*hb)
{mulpoly*hc,*p,*q,*s,*r;
intx;
p=ha;
q=hb;
hc=(mulpoly*)malloc(sizeof(mulpoly));
s=hc;
while((p!
=NULL)&&(q!
=NULL))
if(p->exp==q->exp)
{
x=p->coef-q->coef;
if(x!
=0)
{r=(mulpoly*)malloc(sizeof(mulpoly));
r->exp=p->exp;
r->coef=x;
s->next=r;
s=r;
}
p=p->next;
q=q->next;
}
else
if(p->expexp)
{r=(mulpoly*)malloc(sizeof(mulpoly));
r->coef=-q->coef;
r->exp=q->exp;
s->next=r;
s=r;
q=q->next;
}
Else
{r=(mulpoly*)malloc(sizeof(mulpoly));
r->exp=p->exp;
r->coef=p->coef;
s->next=r;
s=r;
p=p->next;
}
while(p!
=NULL)
{r=(mulpoly*)malloc(sizeof(mulpoly));
r->exp=p->exp;
r->coef=p->coef;
s->next=r;
s=r;
p=p->next;
}
while(q!
=NULL)
{r=(mulpoly*)malloc(sizeof(mulpoly));
r->exp=q->exp;
r->coef=-q->coef;
s->next=r;
s=r;
q=q->next;
}
s->next=NULL;
r=hc;
hc=hc->next;
free(r);
return(hc);
}
多项式相乘:
mulpoly*polymulti(mulpoly*f,mulpoly*g)
{mulpoly*fp,*gp,*hp,*q,*h;
intmaxp,p,r,x;
mulpoly*reverse(mulpoly*q);
maxp=f->exp+g->exp;
h=(mulpoly*)malloc(sizeof(mulpoly));
hp=h;
g=reverse(g);
for(r=maxp;r>=0;r--)
{x=0;fp=f;gp=g;
while((fp!
=NULL)&&(gp!
=NULL))
{p=fp->exp+gp->exp;
if(p>r)
fp=fp->next;
else
if(pgp=gp->next;
else
{x+=fp->coef*gp->coef;
fp=fp->next;
gp=gp->next;
}
}
if(abs(x)>1e-6)
{q=(mulpoly*)malloc(sizeof(mulpoly));
q->exp=r;
q->coef=x;
q->next=NULL;
hp->next=q;
hp=q;
}
}
hp=h;
h=h->next;
free(hp);
returnh;
}
mulpoly*reverse(mulpoly*q)
{mulpoly*p1,*p2;
if(q!
=NULL)
{p1=q->next;
q->next=NULL;
while(p1!
=NULL)
{p2=p1->next;
p1->next=q;
q=p1;
p1=p2;
}
}
returnq;
}
voidpolyout(mulpoly*head)
{
mulpoly*p;
p=head;
while(p!
=NULL)
{printf("%dx%d,",p->coef,p->exp);
p=p->next;
}
printf("\n");
}
福建农林大学计算机与信息学院实验报告
系:
计算机系专业:
计算机科学与技术年级:
2007
姓名:
庄冰钦学号:
071150111实验室号__田514计算机号31
实验时间:
09.4.15下午10、11节指导教师签字:
宁正元成绩:
实验二哈弗曼树及哈弗曼编码译码的实现
一、实验目的和要求
1、掌握树的有关图相关操作算法;
2、熟悉树的基本存储方法;
3、学习利用树求解实际问题。
二、实验内容和原理
1、实验内容:
(1)构造哈弗曼树;
(2)对单个结点编码;(3)输出树;(4)编码;(5)译码。
2、实验原理:
通过树的有关图的相关操作算法,以及树的基本存储方法,利用树来构造哈夫曼树及哈夫曼编码,输出哈夫曼树及哈夫曼编码,完成编码与译码的算法。
三、实验环境
VisualC++6.0及PC机
四、算法描述及实验步骤
五、调试过程
在调试的过程中,出现了一些错误,通过不断调试最终通过
六、实验结果
七、总结
从本次实验中,我更加体会到哈夫曼树的应用,从课上的理论到上机的实际操作,学会了如何构造哈夫曼树,更加的认识哈夫曼树。
附录:
voidselect_2_small(huffnode*ht,intm)//选择2棵根结点权值最小的二叉树的函数
{shortintj,k;
p1=-1;p2=-1;
for(j=0;jif(ht[j].parent==-1)
{if(p1==-1)p1=j;
else
{p2=j;break;}
}
if(ht[p1].weight>ht[p2].weight)//交换p1和p2,使p1的权值小于p2的
{p1=p1+p2;
p2=p1-p2;
p1=p1-p2;
}
for(k=j+1;kif(ht[k].parent!
=-1)continue;
elseif(ht[k].weight{p2=p1;p1=k;}
elseif(ht[k].weight}
voidcreate_huffman_tree()//建立哈夫曼树的函数
{shortinti;
for(i=0;i<2*n-1;i++)//初始化哈夫曼树
{if(ihtree[i].parent=-1;
htree[i].lch=htree[i].rch=-1;
}
for(i=n;i<2*n-1;i++)//构建哈夫曼树
{select_2_small(htree,i);
htree[i].lch=p1;htree[i].rch=p2;
htree[i].weight=htree[p1].weight+htree[p2].weight;
htree[p1].parent=i;htree[p2].parent=i;
}
}
voidmake_huffman_code()//生成哈夫曼树的函数
{shortinti,child,father;
for(i=0;i{child=i;//从叶子开始
father=htree[i].parent;
hcode[i].start=n-1;
while(father!
=-1)//查找直到哈夫曼树根结点的路径
{if(htree[father].lch==child)hcode[i].code[hcode[i].start]=0;//左分枝编码为0
elsehcode[i].code[hcode[i].start]=1;//右分枝编码为1
hcode[i].start--;
child=father;father=htree[father].parent;
}
hcode[i].start++;//校正编码的起始位置
}
}
voidencode_process(char*sp)//编码过程
{cout<<"Text:
"<";
while(*sp)
{p1=*sp-'A';
for(shortintj=hcode[p1].start;jsp++;
}
cout<}
voiddecode_process(char*sp)//译码过程
{shortintnum;
charch,*q;
cout<<"\nHuffmancodes:
"<";
while(*sp)
{num=1;
ch=*sp;q=sp;
while((*sp==ch)&&(num<4))//分割编码
{sp++;num++;
}
p1=2*n-2;//从哈夫曼树根结点开始
while(p1>=n)//搜索直到叶子为止
{if(*q=='0')p1=htree[p1].lch;
elsep1=htree[p1].rch;
q++;
}
switch(p1)
{case0:
cout<<'A';break;
case1:
cout<<'B';break;
case2:
cout<<'C';break;
case3:
cout<<'D';break;
case4:
cout<<'E';break;
case5:
cout<<'F';break;
case6:
cout<<'G';break;
default:
cout<<'H';
}
sp++;
}
cout<}
福建农林大学计算机与信息学院实验报告
系:
计算机系专业:
计算机科学与技术年级:
2007
姓名:
庄冰钦学号:
071150111实验室号__田514__计算机号31
实验时间:
09.4.29下午10、11节指导教师签字:
宁正元成绩:
实验三Dijkstra最短路径或Prim最小生成树(二选一)
一、实验目的和要求
1、掌握图的有关图相关操作算法。
2、熟悉图的基本存储方法。
3、了解掌握图的基本术语。
二、实验内容和原理
实验内容:
①通过输入起点、终点和权重构造一个图;②通过输入,将一个节点作为起点;③找到从起点到各个节点的最短路径;④输出图与及到各个节点的最短短径;
三、实验环境
VisualC++6.0及PC机
四、算法描述及实验步骤
1)初始化。
起源点设置为:
①ds=0,ps为空;②所有其他点:
di=∞,pi=?
;③标记起源点s,记k=s,其他所有点设为未标记的。
2)检验从所有已标记的点k到其直接连接的未标记的点j的距离,并设置:
dj=min[dj,dk+lkj]式中,lkj是从点k到j的直接连接距离。
3)选取下一个点。
从所有未标记的结点中,选取dj中最小的一个i:
di=min[dj,所有未标记的点j]点i就被选为最短路径中的一点,并设为已标记的。
4)找到点i的前一点。
从已标记的点中找到直接连接到点i的点j*,作为前一点,设置:
i=j*
5)标记点i。
如果所有点已标记,则算法完全推出,否则,记k=i,转到2)再继续。
五、调试过程
在调试的过程中,出现了一些错误,通过不断调试最终通过
六、实验结果
七、总结
通过这次的实验,我认识到了求单源最短路径的方法,即用Dijkstra算法。
附录:
voidpath_Dijkstra()//Dijkstra算法求解最短路径的函数
{intset[9]={0};//set向量表示已求得最短路径的终点的集合
inti,j,v,min;
for(i=0;i<9;i++)
{dist[i]=adjmat[0][i];
if(dist[i]!
=mx)prev[i]=0;
elseprev[i]=-1;
}
set[0]=1;//集合set初始时仅包含源点
for(i=1;i<9;i++)
{min=mx;
for(j=0;j<9;j++)//查找当前的最短路径及终点v
if((set[j]==0)&&(dist[j]{min=dist[j];v=j;}
set[v]=1;//终点v并入集合set
for(j=0;j<9;j++)//修正路径长度增加后的最短路径
if((set[j]==0)&&(dist[v]+adjmat[v][j]{dist[j]=dist[v]+adjmat[v][j];
prev[j]=v;}
}
for(i=1;i<9;i++)
{if(i!
=0)
{cout<
v=i;
while(v!
=0)
{v=prev[v];
cout<}
cout<<":
"<cout<}
}
福建农林大学计算机与信息学院实验报告
系:
计算机专业:
计算机科学与技术年级:
2007
姓名:
庄冰钦学号:
071150111实验室号田514计算机号31
实验时间:
09.5.13下午10、11节指导教师签字:
宁正元成绩:
实验四(快速、堆、归并)排序算法的设计(三选一)
一、实验目的和要求
1、掌握常用的排序方法和各种排序方法的特点。
2、熟悉排序的基本概念。
二、实验内容和原理
1、输入一个数组长度随机的数组。
2、对数组中的各个元素进行排序。
三、实验环境
VisualC++6.0及PC机
四、算法描述及实验步骤
1)得到当前序列的最小(大)的元素
2)把这个元素和最后一个元素进行交换,这样当前的最小(大)的元素就放在了序列的最后,而原先的最后一个元素放到了序列的最前面
3)交换可能会破坏堆序列的性质(注意此时的序列是除去已经放在最后面的元素),因此需要对序列进行调整,使之满足于上面堆的性质。
4)重复上面的过程,直到序列调整完毕为止。
五、调试过程
在调试的过程中,出现了一些错误,通过不断调试最终通过
六、实验结果
七、总结
从本次实验我明白了要实现数据的排序也可以通过堆排序。
附录:
voidcreatheap(int*r,inti,intn)
{intj,temp;
temp=r[i];
j=2*i;
while(j<=n)
{if((jj++;
if(temp{r[i]=r[j];
r[j]=temp;
i=j;
j=2*i;
}
else
j=n+1;
}
}
voidheapsort(int*r,intn)
{inti,temp;
for(i=n/2;i>=1;i--)
creatheap(r,i,n);
for(i=n;i>=1;i--)
{temp=r[1];
r[1]=r[i];
r[i]=temp;
creatheap(r,1,i-1);
}
}
福建农林大学计算机与信息学院实验报告
系:
计算机专业:
计算机科学与技术年级:
2007
姓名:
庄冰钦学号:
071150111实验室号_田514_计算机号31
实验时间:
09.5.27下午10、11节指导教师签字:
宁正元成绩:
实验五构造平衡二叉排序树
一、实验目的和要求
1、掌握树型检索的基本概念
2、掌握平衡二叉树的基本概念及原理
二、实验内容和原理
1、实验内容:
构造平衡二叉排序树,实现平衡二叉树结果的输入与输出。
2、实验原理:
构造平衡二叉树的基本思想是在构造的过程中,每当插入一个结点后都去检查是否由于该结点的插入而破坏了AVL树;若出现绝对值超过1的平衡因子,则需要在保持AVL树特性的前提下通过先判断类型后用相应的旋转方法调整使之达到新的平衡。
3、实验方法:
由老师提供程序模板供学生参考,学生在模板的指导下改写程序,在老师的指导下编译、调试、运行。
三、实验环境
VisualC++6.0及PC机
四、
算法描述及实验步骤
五、调试过程
在调试的过程中,出现了一些错误,通过不断调试最终通过
六、实验结果
七、总结
排序也可以用构造平衡二叉树的方法正确的输出。
附录:
voidavltins(keytypek)//插入节点
{
if(root==NULL)
{root=newstructnode;
root->key=k;
root->bf=0;
root->llink=NULL;
root->rlink=NULL;
return;
}
t=NULL;s=root;
p=NULL;q=root;
while(q&&(q->key!
=k))
{if(q->bf)
{
t=p;
s=q;
}
p=q;
if(kkey)q=q->llink;
elseq=q->rlink;
}
if(q)return;
q=newstructnode;
q->key=k;
q->bf=0;
q->llink=q->rlink=NULL;
if(kkey)p->llink=q;
elsep->rlink=q;
if(kkey)r=s->llink;
elser=s->rlink;
p=r;
while(p!
=q)
if(kkey)
{p->bf=-1;
p=p->llink;
}
else
{p->bf=1;
p=p->rlink;
}
switch(s->bf)
{case0:
if(kkey)s->bf=-1;
elses->bf=1;
return;
case-1:
if(k>s->key)
{
s->bf=0;
return;
}
elseif(r->bf<0)LL();
elseLR();
break;
case1:
if(kkey)
{
s->bf=0;
return;
}
elseif(r->bf>0)RR();elseRL();
}
if(t==NULL)root=p;
elseif(s=t->llink)t->llink=p;
elset->rlink=p;
}
voidinorder(structnode*bt)
{if(bt==NULL)
return