图的基本操作.docx
《图的基本操作.docx》由会员分享,可在线阅读,更多相关《图的基本操作.docx(16页珍藏版)》请在冰豆网上搜索。
![图的基本操作.docx](https://file1.bdocx.com/fileroot1/2023-1/21/01992072-4695-408d-bf58-ef2d40344e22/01992072-4695-408d-bf58-ef2d40344e221.gif)
图的基本操作
#include
#include
#include
#defineMAX_VERTEX_NUM100
#defineMAX1000000000
typedefstructArcnode/////邻接表除头结点以外的结点
{
intadjvex;
structArcnode*nextarc;
intweight;
}ArcNode;
typedefstructVnode/////邻接表的头结点
{
intdata;
structArcnode*fistarc;
}Vnode;
VnodeAdjList[MAX_VERTEX_NUM];////有多个头结点,定义为数组形式了
intflag[MAX_VERTEX_NUM];
intcount[MAX_VERTEX_NUM];
intmap[MAX_VERTEX_NUM][MAX_VERTEX_NUM];///////无向图邻接矩阵
intmap2[MAX_VERTEX_NUM][MAX_VERTEX_NUM];////////有向图的邻接矩阵
intmap3[MAX_VERTEX_NUM][MAX_VERTEX_NUM];///////“临时”的邻接矩阵
inttopocount[MAX_VERTEX_NUM];
inttopoflag[MAX_VERTEX_NUM];
intnum[MAX_VERTEX_NUM];/////用于存储深度优先遍历和广度优先遍历的结果
intK;//////表示遍历过的节点数
intchoose;//////主菜单选择变量
intNum,Number;//////Num表示顶点的个数,number表示的为边的个数
voidBuild_VAdjacencyList()///////建立并初始化头结点
{
inti;
for(i=0;i{
AdjList[i].data=i+1;
AdjList[i].fistarc=NULL;
}
}
voidBuildAdjacencyList()///////////建立邻接表,当然,在建立邻接表的同时也建立了此图的图的有向图邻接矩阵以及无向图的邻接矩阵
{
inta,b,c,i,j;
ArcNode*p,*s;
printf("请输入图中顶点的个数:
\n");
scanf("%d",&Num);
Build_VAdjacencyList();
for(i=0;i{
for(j=0;jif(i==j)
{
map[i][j]=0;
map2[i][j]=0;
}
else
{
map[i][j]=MAX;
map2[i][j]=MAX;
}
}
printf("请输入图中边的个数:
\n");
scanf("%d",&Number);
printf("请输入各条边的两个顶点以及边的权值:
\n");
for(i=0;i{
scanf("%d%d%d",&a,&b,&c);
if(map2[a-1][b-1]>c)///////建立此图的有向图的邻接矩阵
{
map2[a-1][b-1]=c;
}
if(map[a-1][b-1]>c)/////这里的2个if为建立此图的无向图的邻接矩阵
map[a-1][b-1]=c;
if(map[b-1][a-1]>c)/////
map[b-1][a-1]=c;
p=AdjList[a-1].fistarc;/////一下是建立邻接表
if(p==NULL)
{
s=(ArcNode*)malloc(sizeof(ArcNode));
s->adjvex=b-1;
s->weight=c;
s->nextarc=NULL;
AdjList[a-1].fistarc=s;
}
else
{
while(p->nextarc!
=NULL)
{
p=p->nextarc;
}
s=(ArcNode*)malloc(sizeof(ArcNode));
s->adjvex=b-1;
s->weight=c;
s->nextarc=NULL;
p->nextarc=s;
}
}
}
voidShowAdjacencyList()///////以邻接表的形式输出各顶点所连接的点
{
if(Num==0)
printf("请先建立有向图!
\n");
else
{
inti;
ArcNode*p;
for(i=0;i{
printf("从%d直接可达的点有:
",i+1);
p=AdjList[i].fistarc;
while(p!
=NULL)
{
printf("%d、",p->adjvex+1);
p=p->nextarc;
}
printf("\n");
}
}
}
voidShowAdjacencyListDegree()//////////////////以邻接表的形式输出各顶点的度
{
if(Num==0)
printf("请先建立有向图!
\n");
else
{
inti,j,sum;
ArcNode*p;
for(i=0;i{
sum=0;
p=AdjList[i].fistarc;
while(p!
=NULL)
{
sum++;
p=p->nextarc;
}
for(j=0;j{
if(j!
=i)
{
p=AdjList[i].fistarc;
while(p!
=NULL)
{
if(p->adjvex==i)
sum++;
p=p->nextarc;
}
}
}
printf("顶点%d的度为:
%d\n",i,sum);
}
}
}
voidTopologicalSortAdjacencyList()///////邻接表的拓扑排序
{
if(Num==0)
printf("请先建立有向图!
\n");
else
{
memset(topocount,0,sizeof(topocount));
memset(topoflag,0,sizeof(topoflag));
inti,sum,k=0;
ArcNode*p;
sum=0;
while(sum{
for(i=0;i{
if(topoflag[i]==0)
{
p=AdjList[i].fistarc;
while(p!
=NULL)
{
topoflag[p->adjvex]=1;
p=p->nextarc;
}
}
}
for(i=0;i{
if(topoflag[i]==0)
{
topoflag[i]=2;
topocount[sum]=i+1;
sum++;
break;
}
}
if(i==Num+1)
{
printf("此有向图有环!
\n");
k=1;
break;
}
for(i=0;i{
if(topoflag[i]==1)
topoflag[i]=0;
}
}
if(k==0)
{
for(i=0;iprintf("%d",topocount[i]);
printf("\n");
}
}
}
voidDFS(ArcNode*s)
{
ArcNode*p;
while(s!
=NULL)
{
if(flag[s->adjvex]==0)
s=s->nextarc;
else
{
flag[s->adjvex]=0;
num[K]=s->adjvex;
K++;
p=AdjList[s->adjvex].fistarc;
DFS(p);
s=s->nextarc;
}
}
}
voidDFSAdjacencyList()///////////////////对邻接表进行深度优先遍历
{
if(Num==0)
printf("请先建立有向图!
\n");
else
{
inti,k;
K=0;
ArcNode*p;
for(i=0;iflag[i]=1;
for(k=0;k{
if(flag[k]==1)
{
num[K]=k;
K++;
p=AdjList[k].fistarc;
DFS(p);
}
}
printf("深度优先遍历的顺序为:
\n");
for(i=0;iprintf("%d",num[i]+1);
printf("\n");
}
}
voidBFSAdjacencyList()///////对邻接表进行广度优先遍历
{
if(Num==0)
printf("请先建立有向图!
\n");
else
{
inti,j;
ArcNode*p;
K=0;
j=0;
for(i=0;iflag[i]=1;
memset(count,0,sizeof(count));
for(i=0;i{
if(flag[i]==1)
{
flag[i]=0;
num[K]=i;
K++;
while(j{
p=AdjList[num[j]].fistarc;
j++;
while(p!
=NULL)
{
if(flag[p->adjvex]==1)
{
num[K]=p->adjvex;
K++;
flag[p->adjvex]=0;
}
p=p->nextarc;
}
}
}
}
printf("广度优先遍历的顺序为:
\n");
for(i=0;iprintf("%d",num[i]+1);
printf("\n");
}
}
voidAdjacencyListPrim()///////////////////用Prim算法对邻接矩阵求最小生成树
{
if(Num==0)
printf("请先建立有向图!
\n");
else
{
intmin1,pi,i,j,ans=0;
for(i=0;i{
flag[i]=0;
count[i]=map[0][i];
}
flag[0]=1;
count[0]=0;
for(i=1;i{
min1=MAX;
for(j=0;j{
if(flag[j]==0&&count[j]{
min1=count[j];
pi=j;
}
}
if(min1==MAX)
{
printf("图不连通!
\n");
return;
}
flag[pi]=1;
for(j=0;j{
if(flag[j]==0&&count[j]>map[pi][j])
count[j]=map[pi][j];
}
}
for(i=0;i{
ans+=count[i];
}
printf("%d\n",ans);
}
}
voidAdjacencyListDijkstra()////////////对邻接矩阵对各顶点到其他顶点的最短距离,在此用的是Dijkstra算法
{
if(Num==0)
printf("请先建立有向图!
\n");
else
{
intmin1,pi,i,j,k;
for(k=0;k{
memset(flag,0,sizeof(flag));
memset(count,0,sizeof(count));
for(i=0;i{
flag[i]=0;
count[i]=map2[k][i];
}
flag[k]=1;
count[k]=0;
for(i=1;i{
min1=MAX;
for(j=0;j{
if(flag[j]==0&&count[j]{
min1=count[j];
pi=j;
}
}
flag[pi]=1;
for(j=0;j{
if(flag[j]==0&&count[j]>count[pi]+map2[pi][j])
count[j]=count[pi]+map2[pi][j];
}
}
for(i=0;i{
map3[k][i]=count[i];
}
}
for(i=0;i{
for(j=0;j{
if(i==j)
continue;
if(map3[i][j]!
=MAX)
printf("顶点%d与顶点%d之间的最短距离为:
%d\n",i+1,j+1,map3[i][j]);
else
printf("顶点%d与顶点%d之间的最短距离为:
+∞\n",i+1,j+1);
}
}
}
}
voidShowMenu()//////////////////////菜单
{
printf("-----------------------------------------------------\n");
printf("|对图的操作如下:
|\n");
printf("-----------------------------------------------------\n");
printf("|1.建立有向图;2.输出该临接表|\n");
printf("|3.输出个顶点的度;4.进行拓扑排序|\n");
printf("|5.深度优先遍历;6.广度优先遍历|\n");
printf("|7.无向图最小生成树;8.有向图求最短路径|\n");
printf("|0.退出|\n");
printf("-----------------------------------------------------\n");
printf("请选择想要进行的操作:
\n");
scanf("%d",&choose);
}
intmain()///////////////////////////////////主函数
{
Num=0;
Number=0;
ShowMenu();
while
(1)
{
if(choose==0)
break;
elseif(choose==1)
{
BuildAdjacencyList();
ShowMenu();
}
elseif(choose==2)
{
ShowAdjacencyList();
ShowMenu();
}
elseif(choose==3)
{
ShowAdjacencyListDegree();
ShowMenu();
}
elseif(choose==4)
{
TopologicalSortAdjacencyList();
ShowMenu();
}
elseif(choose==5)
{
DFSAdjacencyList();
ShowMenu();
}
elseif(choose==6)
{
BFSAdjacencyList();
ShowMenu();
}
elseif(choose==7)
{
AdjacencyListPrim();
ShowMenu();
}
elseif(choose==8)
{
AdjacencyListDijkstra();
ShowMenu();
}
}
return0;
}