实验五 图基本操作的实现.docx

上传人:b****8 文档编号:10937778 上传时间:2023-02-23 格式:DOCX 页数:22 大小:20KB
下载 相关 举报
实验五 图基本操作的实现.docx_第1页
第1页 / 共22页
实验五 图基本操作的实现.docx_第2页
第2页 / 共22页
实验五 图基本操作的实现.docx_第3页
第3页 / 共22页
实验五 图基本操作的实现.docx_第4页
第4页 / 共22页
实验五 图基本操作的实现.docx_第5页
第5页 / 共22页
点击查看更多>>
下载资源
资源描述

实验五 图基本操作的实现.docx

《实验五 图基本操作的实现.docx》由会员分享,可在线阅读,更多相关《实验五 图基本操作的实现.docx(22页珍藏版)》请在冰豆网上搜索。

实验五 图基本操作的实现.docx

实验五图基本操作的实现

实验五图基本操作的实现

【实验课程名称】数据结构

【实验项目名称】单链表基本操作的实现

【实验目的】

1理解图的存储结构;

2掌握邻接矩阵储存结构的图基本操作;

3学会设计实验数据验证程序。

【实验仪器及环境】计算机,windowxp操作系统,VC++6.0

【实验内容及步骤】

1.图的基本操作

constINFINITY=INT_MAX;    //最大值∞

 constMAX_VERTEX_NUM=20;    //最大顶点个数

 typedefenum{DG,DN,AG,AN}GraphKind;

            //类型标志{有向图,有向网,无向图,无向网}

 typedefstructArcCell{    //弧的定义

 VRTypeadj;  //VRType是顶点关系类型。

对无权图,用1或0

         //表示相邻否;对带权图,则为权值类型。

   InfoType*info;        //该弧相关信息的指针

}AdjMatrix[MAX_VERTEX_NUM][MAX_VERTEX_NUM];

typedefstruct{       //图的定义

   VertexTypevexs[MAX_VERTEX_NUM];//顶点信息

   AdjMatrixarcs;        //表示顶点之间关系的二维数组

   intvexnum,arcnum;      //图的当前顶点数和弧(边)数

   GraphKindkind;        //图的种类标志

2.实现的基本操作:

CreateGraph(&G,V,VR);

   初始条件:

V是图的顶点集,VR是图中弧的集合。

   操作结果:

按V和VR的定义构造图G。

DesstroyGraph(&G);

   初始条件:

图G存在。

   操作结果:

销毁图G。

LocateVex(G,u);

   初始条件:

图G存在,u和G中顶点有相同特征。

   操作结果:

若G中存在和u相同的顶点,则返回该顶点在图中位置;

        否则返回其它信息。

 GetVex(G,v);

   初始条件:

图G存在,v是G中某个顶点。

   操作结果:

返回v的值。

FirstAdjVex(G,v);

  初始条件:

图G存在,v是G中某个顶点。

  操作结果:

返回v的第一个邻接点。

若该顶点在G中没有邻接点,

        则返回"空"。

NextAdjVex(G,v,w);

  初始条件:

图G存在,v是G中某个顶点,w是v的邻接顶点。

操作结果:

返回v的(相对于w的)下一个邻接点。

若w是v的最后一个邻接点,则返回"空"。

PutVex(&G,v,value);

   初始条件:

图G存在,v是G中某个顶点。

   操作结果:

对v赋值value。

InsertVex(&G,v);

 初始条件:

图G存在,v和图中顶点有相同特征。

 操作结果:

在图G中增添新顶点v。

DeleteVex(&G,v);

 初始条件:

图G存在,v是G中某个顶点。

 操作结果:

删除G中顶点v及其相关的弧。

InsertArc(&G,v,w);

   初始条件:

图G存在,v和w是G中两个顶点。

操作结果:

在G中增添弧,若G是无向的,则还增添对称弧

DeleteArc(&G,v,w);

 初始条件:

图G存在,v和w是G中两个顶点。

操作结果:

在G中删除弧,若G是无向的,则还删除对称弧

DFSTraverse(G,Visit());

  初始条件:

图G存在,Visit是顶点的应用函数。

操作结果:

对图G进行深度优先遍历。

遍历过程中对每个顶点调用函数Visit一次且仅一次。

一旦visit()失败,则操作失败。

BFSTraverse(G,Visit());

  初始条件:

图G存在,Visit是顶点的应用函数。

操作结果:

对图G进行广度优先遍历。

遍历过程中对每个顶点调用函数Visit一次且仅一次。

一旦visit()失败,则操作失败。

基本操作的代码:

#include

#include

usingnamespacestd;

#defineint_max10000

#defineinf9999

#definemax20

//…………………………………………邻接矩阵定义……………………

typedefstructArcCell{

intadj;

char*info;

}ArcCell,AdjMatrix[20][20];

typedefstruct{

charvexs[20];

AdjMatrixarcs;

intvexnum,arcnum;//有向图的当前顶点数和弧数

}MGraph_L;

//^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

intlocalvex(MGraph_LG,charv){//返回V的位置

inti=0;

while(G.vexs[i]!

=v){

++i;

}

returni;

}

intcreatMGraph_L(MGraph_L&G){//创建图用邻接矩阵表示

charv1,v2;

inti,j,w;

cout<<"…………创建无向图…………"<

(46)不包括“()”"<

cin>>G.vexnum>>G.arcnum;

for(i=0;i!

=G.vexnum;++i){

cout<<"输入顶点"<

cin>>G.vexs[i];

}

for(i=0;i!

=G.vexnum;++i)

for(j=0;j!

=G.vexnum;++j){

G.arcs[i][j].adj=int_max;

G.arcs[i][j].info=NULL;

}

for(intk=0;k!

=G.arcnum;++k){

cout<<"输入一条边依附的顶点和权:

(ab3)不包括“()”"<

cin>>v1>>v2>>w;//输入一条边依附的两点及权值

i=localvex(G,v1);//确定顶点V1和V2在图中的位置

j=localvex(G,v2);

G.arcs[i][j].adj=w;

G.arcs[j][i].adj=w;

}

cout<<"图G邻接矩阵创建成功!

"<

returnG.vexnum;

}

voidljjzprint(MGraph_LG){

inti,j;

for(i=0;i!

=G.vexnum;++i){

for(j=0;j!

=G.vexnum;++j)

cout<

cout<

}

}

intvisited[max];//访问标记

intwe;

typedefstructarcnode{//弧结点

intadjvex;//该弧指向的顶点的位置

structarcnode*nextarc;//弧尾相同的下一条弧

char*info;//该弧信息

}arcnode;

typedefstructvnode{//邻接链表顶点头接点

chardata;//结点信息

arcnode*firstarc;//指向第一条依附该结点的弧的指针

}vnode,adjlist;

typedefstruct{//图的定义

adjlistvertices[max];

intvexnum,arcnum;

intkind;

}algraph;

//…………………………………………队列定义……………………

typedefstructqnode{

intdata;

structqnode*next;

}qnode,*queueptr;

typedefstruct{

queueptrfront;

queueptrrear;

}linkqueue;

//………………………………………………………………………

typedefstructacr{

intpre;//弧的一结点

intbak;//弧另一结点

intweight;//弧的权

}edg;

intcreatadj(algraph&gra,MGraph_LG){//用邻接表存储图

inti=0,j=0;

arcnode*arc,*tem,*p;

for(i=0;i!

=G.vexnum;++i){

gra.vertices[i].data=G.vexs[i];

gra.vertices[i].firstarc=NULL;

}

for(i=0;i!

=G.vexnum;++i){

for(j=0;j!

=G.vexnum;++j){

if(gra.vertices[i].firstarc==NULL){

if(G.arcs[i][j].adj!

=int_max&&j!

=G.vexnum){

arc=(arcnode*)malloc(sizeof(arcnode));

arc->adjvex=j;

gra.vertices[i].firstarc=arc;

arc->nextarc=NULL;

p=arc;

++j;

while(G.arcs[i][j].adj!

=int_max&&j!

=G.vexnum){

tem=(arcnode*)malloc(sizeof(arcnode));

tem->adjvex=j;

gra.vertices[i].firstarc=tem;

tem->nextarc=arc;

arc=tem;

++j;

}

--j;

}

}

else{

if(G.arcs[i][j].adj!

=int_max&&j!

=G.vexnum){

arc=(arcnode*)malloc(sizeof(arcnode));

arc->adjvex=j;

p->nextarc=arc;

arc->nextarc=NULL;

p=arc;

}

}

}

}

gra.vexnum=G.vexnum;

gra.arcnum=G.arcnum;

cout<<"图G邻接表创建成功!

"<

return1;

}

voidadjprint(algraphgra){

inti;

for(i=0;i!

=gra.vexnum;++i){

arcnode*p;

cout<

p=gra.vertices[i].firstarc;

while(p!

=NULL){

cout<adjvex;

p=p->nextarc;

}

cout<

}

}

intfirstadjvex(algraphgra,vnodev){//返回依附顶点V的第一个点

//即以V为尾的第一个结点

if(v.firstarc!

=NULL)

returnv.firstarc->adjvex;

}

intnextadjvex(algraphgra,vnodev,intw){//返回依附顶点V的相对于W的下一个顶点

arcnode*p;

p=v.firstarc;

while(p!

=NULL&&p->adjvex!

=w){

p=p->nextarc;

}

if(p->adjvex==w&&p->nextarc!

=NULL){

p=p->nextarc;

returnp->adjvex;

}

if(p->adjvex==w&&p->nextarc==NULL)

return-10;

}

intinitqueue(linkqueue&q){//初始化队列

q.rear=(queueptr)malloc(sizeof(qnode));

q.front=q.rear;

if(!

q.front)

return0;

q.front->next=NULL;

return1;

}

intenqueue(linkqueue&q,inte){//入队

queueptrp;

p=(queueptr)malloc(sizeof(qnode));

if(!

p)

return0;

p->data=e;

p->next=NULL;

q.rear->next=p;

q.rear=p;

return1;

}

intdequeue(linkqueue&q,int&e){//出队

queueptrp;

if(q.front==q.rear)

return0;

p=q.front->next;

e=p->data;

q.front->next=p->next;

if(q.rear==p)

q.rear=q.front;

free(p);

return1;

}

intqueueempty(linkqueueq){//判断队为空

if(q.front==q.rear)

return1;

return0;

}

voidbfstra(algraphgra)//广度优先遍历

{

inti,e;

linkqueueq;

for(i=0;i!

=gra.vexnum;++i)

visited[i]=0;

initqueue(q);

for(i=0;i!

=gra.vexnum;++i)

if(!

visited[i])

{visited[i]=1;

cout<

enqueue(q,i);

while(!

queueempty(q))

{

dequeue(q,e);

//cout<<""<

for(we=firstadjvex(gra,gra.vertices[e]);we>=0;we=nextadjvex(gra,gra.vertices[e],we))

{

if(!

visited[we])

{

visited[we]=1;

cout<

enqueue(q,we);

}

}

}

}

}

intdfs(algraphgra,inti);//声明DFS

intdfstra(algraphgra)

{

inti,j;

for(i=0;i!

=gra.vexnum;++i)

{

visited[i]=0;

}

for(j=0;j!

=gra.vexnum;++j)

{

if(visited[j]==0)

dfs(gra,j);

}

return0;

}

intdfs(algraphgra,inti)

{

visited[i]=1;

intwe1;

//cout<

cout<

//cout<

for(we=firstadjvex(gra,gra.vertices[i]);we>=0;we=nextadjvex(gra,gra.vertices[i],we))

{

//cout<

we1=we;

//cout<

if(visited[we]==0)

//cout<<

dfs(gra,we);//<

//cout<

we=we1;

//cout<

}

return12;

}

intbfstra_fen(algraphgra)//求连通分量

{

inti,j;

for(i=0;i!

=gra.vexnum;++i)

{

visited[i]=0;

}

for(j=0;j!

=gra.vexnum;++j)

{

if(visited[j]==0)

{

dfs(gra,j);

cout<

}

}

return0;

}

typedefstruct{

intadjvex;

intlowcost;

}closedge;

intprim(intg[][max],intn)//最小生成树PRIM算法

{

intlowcost[max],prevex[max];//LOWCOST[]存储当前集合U分别到剩余结点的最短路径

//prevex[]存储最短路径在U中的结点

inti,j,k,min;

for(i=2;i<=n;i++)//n个顶点,n-1条边

{

lowcost[i]=g[1][i];//初始化

prevex[i]=1;//顶点未加入到最小生成树中

}

lowcost[1]=0;//标志顶点1加入U集合

for(i=2;i<=n;i++)//形成n-1条边的生成树

{

min=inf;

k=0;

for(j=2;j<=n;j++)//寻找满足边的一个顶点在U,另一个顶点在V的最小边

if((lowcost[j]

=0))

{

min=lowcost[j];

k=j;

}

printf("(%d,%d)%d\t",prevex[k]-1,k-1,min);

lowcost[k]=0;//顶点k加入U

for(j=2;j<=n;j++)//修改由顶点k到其他顶点边的权值

if(g[k][j]

{

lowcost[j]=g[k][j];

prevex[j]=k;

}

printf("\n");

}

return0;

}

intacrvisited[100];//kruscal弧标记数组

intfind(intacrvisited[],intf)

{

while(acrvisited[f]>0)

f=acrvisited[f];

returnf;

}

voidkruscal_arc(MGraph_LG,algraphgra)

{

edgedgs[20];

inti,j,k=0;

for(i=0;i!

=G.vexnum;++i)

for(j=i;j!

=G.vexnum;++j)

{

if(G.arcs[i][j].adj!

=10000)

{

edgs[k].pre=i;

edgs[k].bak=j;

edgs[k].weight=G.arcs[i][j].adj;

++k;

}

}

intx,y,m,n;

intbuf,edf;

for(i=0;i!

=gra.arcnum;++i)

acrvisited[i]=0;

for(j=0;j!

=G.arcnum;++j)

{

m=10000;

for(i=0;i!

=G.arcnum;++i)

{

if(edgs[i].weight

{

m=edgs[i].weight;

x=edgs[i].pre;

y=edgs[i].bak;

n=i;

}

}

//cout<

//cout<

buf=find(acrvisited,x);

edf=find(acrvisited,y);

//cout<

edgs[n].weight=10000;

if(buf!

=edf)

{

acrvisited[buf]=edf;

cout<<"("<

cout<

}

}

}

voidmain()

{

algraphgra;

MGraph_LG;

inti,d,g[20][20];

chara='a';

d=creatMGraph_L(G);

creatadj(gra,G);

vnodev;

cout<

若该图为非强连通图(含有多个连通分量)时"<

<<"最小生成树不存在,则显示为非法值。

"<

cout<<"…………………菜单……………………"<

cout<<"0、显示该图的邻接矩阵……………………"<

cout<<"1、显示该图的邻接表……………………"<

cout<<"2、深度优先遍历…………………………"<

cout<<"3、广度优先遍历…………………………"<

cout<<"4、最小生成树PRIM算法…………………"<

cout<<"5、最小生成树KRUSCAL算法………………"<

cout<<"6、该图的连通分量………………………"<

ints;

chary='y';

while(y='y')

{

cout<<"请选择菜单:

"<

cin>>s;

switch(s)

{

case0:

cout<<"邻接矩阵显示如下:

"<

ljjzprint(G);

break;

case1:

cout<<"邻接表显示如下:

"<

adjprint(gra);

break;

case2:

cout<<"广度优先遍历:

";

bfstra(gra);

cout<

break;

case3:

for(i=0;i!

=gra.vexnum;++i)

{

visited[i]=0;

}

cout<<"深度优先遍历:

";

d

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 法律文书 > 调解书

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1