数据结构实验报告图的遍历讲解Word文件下载.docx
《数据结构实验报告图的遍历讲解Word文件下载.docx》由会员分享,可在线阅读,更多相关《数据结构实验报告图的遍历讲解Word文件下载.docx(19页珍藏版)》请在冰豆网上搜索。
![数据结构实验报告图的遍历讲解Word文件下载.docx](https://file1.bdocx.com/fileroot1/2023-1/1/2b917c11-3b29-498e-a6c0-d820b5d643e3/2b917c11-3b29-498e-a6c0-d820b5d643e31.gif)
intadjvex;
structnode*next}EdgeNode;
vextypevex;
EdgeNode*firstedge;
}VexNode;
VexNodeadjvex[MAXSIZE];
intn,e;
}ALGraph;
四、概要设计
为了实现上述程序功能,代码如下:
#include<
stdio.h>
stdlib.h>
string.h>
typedefstructnode{//边表结点
intadj;
//边表结点数据域
structnode*next;
}node;
typedefstructvnode{//顶点表结点
charname[20];
node*fnext;
}vnode,AList[20];
AListList;
//邻接表
intv,e;
//顶点树和边数
}*Graph;
//建立无向邻接表
GraphCreatDG(){
GraphG;
inti,j,k;
node*s;
G=malloc(20*sizeof(vnode));
printf("
请输入图的顶点数和边数(空格隔开):
"
);
scanf("
%d%d"
&
G->
v,&
e);
//读入顶点数和边数
for(i=0;
i<
v;
i++){
printf("
请输入图中第%d元素:
i+1);
scanf("
%s"
G->
List[i].name);
//读入顶点信息
G->
List[i].fnext=NULL;
//边表置为空表
}
for(k=0;
k<
e;
k++){
请请输入第%d条边的两顶点序号(空格隔开):
k+1);
i,&
j);
//读入边(Vi,Vj)的顶点对序号;
s=(node*)malloc(sizeof(node));
//生成边表结点
s->
adj=j;
next=G->
List[i].fnext;
List[i].fnext=s;
//将新结点*s插入顶点Vi的边表头部
adj=i;
//邻接点序号为i
List[j].fnext;
List[j].fnext=s;
//将新结点*s插入顶点Vj的边表头部
}
returnG;
}
//有向邻接图
GraphCreatAG(){
node*q;
请输入图的顶点数和边数【空格隔开】:
for(i=0;
//读入顶点信息
for(k=0;
请请输入第%d边的两顶点序号【空格隔开】:
q=(node*)malloc(sizeof(node));
//生成新边表结点s
q->
//邻接点序号为j
List[i].fnext=q;
//输出图的邻接表
voidPrint(GraphG){
inti;
node*p;
\t=======邻接表========\n"
p=G->
%d|%3s"
i,G->
while(p){
->
%3s"
List[p->
adj].name);
%d"
p->
adj);
p=p->
next;
\n"
typedefstruct{
charvex[20];
}Lists[20];
Listsl;
intedge[20][20];
//邻接矩阵
intv1,e1;
//顶点数和弧数
}AGraph;
intdata;
/*某顶点与已构造好的部分生成树的顶点之间权值最小的顶点*/
intlowcost;
/*某顶点与已构造好的部分生成树的顶点之间的最小权值*/
}ClosEdge[20];
/*用普里姆算法求最小生成树时的辅助数组*/
voidCreateAN(AGraph*G1){
/*构造邻接矩阵结构的图G*/
inti,j,k,w;
G1->
v1,&
e1);
for(i=1;
=G1->
v1;
请输入图%d号元素:
i);
l[i].vex);
i++)//初始化邻接矩阵
for(j=1;
j<
j++)
G1->
edge[i][j]=9;
for(k=1;
e1;
请输入两顶点及边的权值(空格隔开):
%d%d%d"
j,&
w);
edge[i][j]=w;
edge[j][i]=w;
voidPrintAN(AGraph*G1){
inti,j;
\t=======邻接矩阵========\n"
%3d"
G1->
edge[i][j]);
//输出各顶点的度数
voidDu(GraphG){
\n<
----各点度数---->
顶点%2s的度为:
j=0;
j++;
p=p->
%d\n"
j);
//栈
typedefstructstack{
intx;
structstack*next;
}stack;
intpush(stack*s,inti){
stack*p;
p=(stack*)malloc(sizeof(stack));
p->
x=i;
next=s->
s->
next=p;
return1;
intpop(stack*s,intj){
stack*p=s->
//保存栈顶指针
j=p->
x;
next=p->
//将栈顶元素摘下
free(p);
//释放栈顶空间
returnj;
//拓扑排序
voidTopo(GraphG,stack*s){
inti,k,count;
intj=0;
intindegree[20]={0};
p=G->
;
while(p!
=NULL){
indegree[p->
adj]++;
p=p->
i++)
if(indegree[i]==0)
push(s,i);
count=0;
while(s->
next!
i=pop(s,j);
%2s"
++count;
for(p=G->
p!
=NULL;
p=p->
next){
k=p->
adj;
if(!
(--indegree[k]))
push(s,k);
if(count<
v)printf("
有回路!
voidDFS(GraphG,inti,intflag[]){
flag[i]=1;
while(p){
if(!
flag[p->
adj])
DFS(G,p->
adj,flag);
//深度优先遍历
voidDFSTravel(GraphG){
intflag[20];
//标志数组
flag[i]=0;
flag[i])
DFS(G,i,flag);
//建立队列
int*elem;
intfront,rear;
}*Queue;
//队列初始化
voidInitQueue(QueueQ){
Q->
elem=(int*)malloc(20*sizeof(int));
Q->
elem)
exit(0);
front=Q->
rear=0;
//入队
voidEnter(QueueQ,inte){
if((Q->
rear+1)%20!
=Q->
front)
Q->
elem[Q->
rear]=e;
else
队列满!
rear=(Q->
rear+1)%20;
//出队
voidLeave(QueueQ,inte){
if(Q->
rear!
e=Q->
front];
队列空!
front=(Q->
front+1)%20;
//广度优先遍历
voidBFSTravel(GraphG){
QueueQ;
inti,j=0;
Q=malloc(sizeof(20));
InitQueue(Q);
if(flag[i]==0){
flag[i]=1;
printf("
%2s"
Enter(Q,i);
while(Q->
front!
=Q->
rear){
Leave(Q,j);
//队头元素出队并置为j
p=G->
while(p!
if(flag[p->
adj]==0){
printf("
flag[p->
adj]=1;
Enter(Q,p->
}
p=p->
}
}
intminimum(ClosEdgecl,intvnum){
intw,p;
w=1000;
=vnum;
if(cl[i].lowcost!
=0&
&
cl[i].lowcost<
w){
w=cl[i].lowcost;
p=i;
returnp;
voidPrim(AGraph*G1,intu){
ClosEdgeclosedge;
for(j=1;
j++)/*辅助数组初始化*/
if(j!
=u){
closedge[j].data=u;
closedge[j].lowcost=G1->
edge[u][j];
closedge[u].lowcost=0;
/*初始,U={u}*/
k=minimum(closedge,G1->
v1);
/*求出生成树的下一个顶点*/
%d-----%d\n"
closedge[k].data,k);
/*输出生成树的边*/
closedge[k].lowcost=0;
/*第k顶点并入U集*/
j++)/*新顶点并入U后,修改辅助数组*/
if(G1->
edge[k][j]<
closedge[j].lowcost){
closedge[j].data=k;
closedge[j].lowcost=G1->
edge[k][j];
}
//菜单列表
voidmenu(){
\t**********************图的遍历问题**********************\n"
\t\t-------1.建立无向邻接图---------\n"
\t\t-------2.建立有向邻接图---------\n"
\t\t-------3.建立无向邻接矩阵---------\n"
\t\t-------4.输出各顶点的度---------\n"
\t\t-------5.拓扑排序---------\n"
\t\t-------6.深度优先遍历---------\n"
\t\t-------7.广度优先遍历---------\n"
\t\t-------8.prim算法生成最小生成树---------\n"
\t\t-------9-退出---------\n"
\t********************************************************\n"
//主函数
voidmain(){
AGraphG1;
intchoice,u;
stack*s=(stack*)malloc(sizeof(stack));
next=NULL;
while
(1){
menu();
请输入选择:
choice);
switch(choice)
{
case1:
G=CreatDG();
Print(G);
printf("
\n\n"
break;
case2:
G=CreatAG();
case3:
CreateAN(&
G1);
PrintAN(&
case4:
Du(G);
case5:
拓扑排序:
Topo(G,s);
case6:
深度优先遍历:
DFSTravel(G);
case7:
广度优先遍历:
BFSTravel(G);
case8:
printf("
请输入起点序号:
scanf("
u);
Prim算法:
Prim(&
G1,u);
break;
case9:
exit(0);
default:
输入错误,请重新输入:
\n\n"
五、使用说明
1、程序名为实验图的遍历.exe,运行坏境为VC6.0.程序执行后显示如图所示:
2、建立无向邻接图
3、输出各顶点的度
4、进行深度优先遍历
5、进行广度优先遍历
6、建立有向邻接图
7、拓扑排序
8、建立无向邻接矩阵
9、prim算法生成最小生成树
八、实验总结
通过对本次试验的学习,使我们明白了合作分工的重要性,这并不是一个容易的过程,中间碰到了许多问题,但我们都一一解决,有关于图这部分的内容很复杂,但是却非常重要,掌握好图的遍历有助于我们提升今后解决实际问题的能力,对我们非常有帮助。
注:
模块分工
张纪远(2014100518)主函数的编写及页面的设计;
段慧娟(2014100512)建立无向连接图及有向连接图;
梁丽蓉(2014100526)建立无向邻接矩阵及及输出各顶点的度;
周振军(2014100551)拓扑排序及深度优先遍历;
朱新祥(2014100552)广度优先遍历及prim算法生成最小生成树。