数据结构第五次上机实验报告.docx
《数据结构第五次上机实验报告.docx》由会员分享,可在线阅读,更多相关《数据结构第五次上机实验报告.docx(18页珍藏版)》请在冰豆网上搜索。
数据结构第五次上机实验报告
二叉树的应用及图的创建和遍历
一、实验目的
1.熟练掌握二叉树的应用
2.理解图的抽象数据类型的定义,及在C语言环境中的表示方法。
3.理解图的基本操作的算法,及在C语言环境中一些主要基本操作的实现。
4.在C语言环境下实现图的应用操作:
①使用邻接矩阵存储结构,实现无向网的创建和输出。
②使用邻接表存储结构,实现无向网的创建和输出
③利用基本操作集,实现采用邻接表表示的无向图的非递归的广度优先遍历算法
二、实验内容
1.构造haffman树,并求haffman编码(P97,14题中数据为主
程序代码
#include
#defineHUGE999
#defineN8
#defineM2*N-1
structHuffmanNode{
intweight;
intparent;
intleft;
intright;
};
structHuffmanCode{
intbit[N];
intstart;
};
intweight[]={2,3,5,7,11,13,17,19,0,0,0,0,0,0,0};//将各个顶点权值赋给数组
structHuffmanNodeHT[M];//通过改变权值,可以构造不同的structHuffmanCodeHC[N];//哈弗曼树
voidinit()//只有一个循环,时间复杂度为o(M)
{
inti;
for(i=0;i{
HT[i].parent=-1;
HT[i].weight=weight[i];
HT[i].left=-1;
HT[i].right=-1;
}
}
intminimum()//时间复杂度为o(M)
{
inti,k;
intmin=HUGE;
for(i=0;iif(min>weight[i]&&weight[i]!
=0){
min=weight[i];
k=i;
}
weight[k]=HUGE;
returnk;
}
voidhuffmantree()//时间复杂度为o(M-N)
{
inti,l,r;
for(i=N;i{
l=minimum();
r=minimum();
HT[l].parent=i;
HT[r].parent=i;
HT[i].left=l;
HT[i].right=r;
HT[i].weight=HT[l].weight+HT[r].weight;
weight[i]=HT[i].weight;
}
}
voidhuffmancode()//循环嵌套,时间复杂度为o(N^2)
{
inti,p,j,c;
structHuffmanCodecd;
for(i=0;i{
cd.start=N-1;
c=i;
p=HT[c].parent;
while(p!
=0){
if(HT[p].left==c)
cd.bit[cd.start]=0;
elsecd.bit[cd.start]=1;
cd.start--;
c=p;
p=HT[c].parent;
}
for(j=cd.start+1;jHC[i].bit[j]=cd.bit[j];
HC[i].start=cd.start;
}
}
intmain()
{
inti,j;
init();
huffmantree();
for(i=0;iprintf("%5d%5d%5d%5d\n",HT[i].weight,HT[i].parent,HT[i].left,HT[i].right);
printf("\n");
huffmancode();
for(i=0;iprintf("%5d:
",HT[i].weight);
for(j=HC[i].start+2;jprintf("%d",HC[i].bit[j]);
printf("\n");
}
}
⏹关键部分加注释(见源代码注释)
⏹执行结果
⏹算法分析(见源代码注释)
2.无向图创建和输出(邻接矩阵)
程序代码
#include
#include
#include
#defineMAXSIZE999
#defineN6
intvisited[N]={0,0,0,0,0,0};
intmartix[N][N];
voidsetup()//创建一个无向网
{
intu,v,i,j,w;//u,v为顶点数字,w为权值
printf("请输入相邻顶点和权值:
\n");
for(i=0;ifor(j=0;j{
if(i==j)
martix[i][j]=0;//将对角线赋为0
else
martix[i][j]=MAXSIZE;
}
scanf("%d%d%d",&u,&v,&w);
while(u>=0)
{
martix[u][v]=w;//因为是无向网,呈对称分布
martix[v][u]=w;
scanf("%d%d%d",&u,&v,&w);
}
}
voidprint()//创建一个无向网
{inti,j;//双循环,时间复杂度为o(N^2)
for(i=0;i{for(j=0;jprintf("%4d",martix[i][j]);
printf("\n");
}
}
voidlookfor(intk)//查找函数
{intj;//单循环,时间复杂度为o(N)
if(k>=N)
{printf("该顶点不在图中");
exit(0);}
else
for(j=0;jprintf("%4d",martix[k][j]);
}
intmain()
{intn;
setup();
print();
printf("请输入所要检索的顶点数字标号:
\n");
scanf("%d",&n);
lookfor(n);
}
⏹关键部分加注释(见源代码注释)
⏹执行结果
⏹算法分析(见源代码注释)
3.无向图创建和输出(邻接表)
源代码
#include
#include
#include
#defineMAXVERTEX100
structnode{
intvertex;
structnode*next;
};
structnode*adjlist[MAXVERTEX];
voidsetup(intn)//两个并列循环,时间复杂度均为o(n)
{
intu,v,i;
structnode*p;
for(i=0;iadjlist[i]=NULL;
scanf("%d%d",&u,&v);
while(u>=0)
{
p=(structnode*)malloc(sizeof(structnode));
p->vertex=v;
p->next=adjlist[u];
adjlist[u]=p;
scanf("%d%d",&u,&v);
}
}
voidprint(intn)//输出邻接表
{//设每个顶点平均边数为e,则时间复杂度为o(n*e)
structnode*p;
inti;
for(i=0;i{printf("%d",i);
p=adjlist[i];
while(p!
=NULL)
{printf("%d",p->vertex);
p=p->next;
}
printf("\n");
}
}
voidlookfor(intk,intn)//查找顶点是否在邻接表
{structnode*p;
if(k>=n)
{printf("该顶点不在图中");
exit(0);}
else
printf("%d",k);
p=adjlist[k];
while(p!
=NULL)
{printf("%d",p->vertex);
p=p->next;
}
}
intmain()
{
intn,i,k;
printf("pleaseinputvertexnumberofgraph:
");
scanf("%d",&n);
setup(n);
print(n);
k=2;
lookfor(k,n);
}
⏹关键部分加注释(见源代码注释)
⏹执行结果
4.非递归广度优先遍历
源代码
#include
#include
#include
#defineMAXSIZE100
#defineMAXVERTEX100
structnode{
intvertex;
structnode*next;
};
structqueue{
intelement[MAXSIZE];
intfront;
intrear;
};
structnode*adjlist[MAXVERTEX];
intvisited[MAXVERTEX];
structqueueq;
voidinit()
{
q.front=q.rear=0;
}
voidinqueue(intx)
{
q.rear=(q.rear+1)%MAXSIZE;
q.element[q.rear]=x;
}
intoutqueue()
{
q.front=(q.front+1)%MAXSIZE;
returnq.element[q.front];
}
intisempty()
{
returnq.front==q.rear;
}
voidsetup(intn)////两个并列循环,时间复杂度均为o(n)
{
intu,v,i;
structnode*p;
for(i=0;iadjlist[i]=NULL;
scanf("%d%d",&u,&v);
while(u>=0)
{
p=(structnode*)malloc(sizeof(structnode));
p->vertex=v;
p->next=adjlist[u];
adjlist[u]=p;
scanf("%d%d",&u,&v);
}
}
voidBFS(intu)//设有n个顶点和e条边,每个顶点均入队一
{structnode*p;//次,时间复杂度为o(n+e)
intv;
printf("%d",u);
visited[u]=1;
inqueue(u);
do
{
v=outqueue();
p=adjlist[v];
while(p!
=NULL)
{
if(visited[p->vertex]==0)
{
v=p->vertex;
visited[v]=1;
printf("%d",v);
inqueue(v);
}
p=p->next;
}
}while(!
isempty());
}
voidprint(intn)//输出邻接表设每个
{//顶点平均边数为e,则时间复杂度为o(n*e)
structnode*p;
inti;
for(i=0;i{printf("%d",i);
p=adjlist[i];
while(p!
=NULL)
{printf("%d",p->vertex);
p=p->next;
}
printf("\n");
}
}
voidlookfor(intk,intn)
{structnode*p;
if(k>=n)
{printf("该顶点不在图中");
exit(0);}
else
printf("%d",k);
p=adjlist[k];
while(p!
=NULL)
{printf("%d",p->vertex);
p=p->next;
}
}
intmain()
{
intn,i,k;
k=1;
init();
printf("pleaseinputvertexnumberofgraph:
");
scanf("%d",&n);
for(i=0;ivisited[i]=0;
setup(n);
print(n);
lookfor(k,n);
printf("orderintraversbybfs:
");
BFS(0);
}
⏹关键部分加注释(见源代码注释)
⏹执行结果
⏹算法分析(见源代码注释)
⏹总结
图的两种存储结构,各有各的好处,邻接表较复杂一些,但其是在单链表的基础上,用数组存放头指针而已。
关键是BFS和DFS,应熟练掌握
⏹实验体会
图的存储结构及遍历比起前面的单链表,栈,队列,树,较为复杂,但其遍历可以借鉴树的遍历,同时对于BFS,DFS的非递归算法,可以灵活利用栈与队列,实现算法