\ue50a时间:　\ue50b\ue50a2021/5/22　11:47:45　\ue50b\ue50a来源:互联网　\ue50b#　include　　#　include　　#　include　　#　include　　#　define　MAX_VERTEX_NUM　20　#　define　MAX_NAME　3　#　define　Status　int　#　define　ERROR　1　#　define　OK　0　typedef　char　VertexType　[　MAX_NAME　]　;　typedef　int　InfoType　;　typedef　enum　{　DG　,　DN　,　AG　,　AN　}　GraphKind　;　//{有向图,有向网,无向图,无向网}　typedef　struct　ArcNode　{　int　adjvex　;　//该弧所指向的顶点的位置　InfoType　*　info　;　//网的权值指针　struct　ArcNode　*　nextarc　;　//指向下一条弧的指针　}　ArcNode　;　//表结点　typedef　struct　{　VertexType　data　;　//顶点信息　(三个域)　ArcNode　*　firstarc　;　//第一个表结点的地址,指向第一条依附于该顶点的弧　}　VNode　;　//头结点　typedef　struct　{　VNode　vertices　[　MAX_VERTEX_NUM　]　;　//定义一个这个类型的数组　int　vexnum　,　arcnum　;　//图的当前顶点数和弧数　int　kind　;　//图的种类标志　}　ALGraph　;　//邻接表　//求顶点位置的算法　int　LocateVex　(　ALGraph　G　,　VertexType　u　)　{　int　i　;　for　(　i　=　0　;　i　<　G　.　vexnum　;　++　i　)　{　if　(　strcmp　(　u　,　G　.　vertices　[　i　]　.　data　)　==　0　)　return　i　;　}　return　-　1　;　}　//求顶点信息的算法　VertexType　*　GetVex　(　ALGraph　G　,　int　v　)　{　if　(　v　>=　G　.　vexnum　||　v　<　0　)　exit　(　1　)　;　//出现错误退出　printf　(　"此顶点的信息为%s\n"　,　G　.　vertices　[　v　]　.　data　)　;　return　&　G　.　vertices　[　v　]　.　data　;　}　//对顶点赋新值的算法　Status　PutVex　(　ALGraph　*　G　,　VertexType　v　,　VertexType　value　)　{　int　i　;　i　=　LocateVex　(　*　G　,　v　)　;　if　(　i　<　-　1　)　{　strcpy　(　(　*　G　)　.　vertices　[　i　]　.　data　,　value　)　;　return　OK　;　}　return　ERROR　;　}　//求顶点的第一个邻接顶点序号的算法　int　FirstAdjVex　(　ALGraph　G　,　VertexType　v　)　{　ArcNode　*　p　;　int　i　;　i　=　LocateVex　(　G　,　v　)　;　//i为顶点v在图G中的序号　p　=　G　.　vertices　[　i　]　.　firstarc　;　//指针指向　if　(　p　)　return　p　->　adjvex　;　//返回位置　else　//p==NULL　return　-　1　;　}　//求顶点v相对于某顶点w的下一个邻接顶点序号的算法　int　NextAdjVex　(　ALGraph　G　,　VertexType　v　,　VertexType　w　)　{　ArcNode　*　p　;　int　v1　,　w1　;　v1　=　LocateVex　(　G　,　v　)　;　w1　=　LocateVex　(　G　,　w　)　;　p　=　G　.　vertices　[　v1　]　.　firstarc　;　while　(　p　&&　p　->　adjvex　!=　w1　)　p　=　p　->　nextarc　;　if　(　!　p　||　!　p　->　nextarc　)　return　-　1　;　else　return　p　->　nextarc　->　adjvex　;　}　//插入新顶点的算法　void　InsertVex　(　ALGraph　*　G　,　VertexType　v　)　{　strcpy　(　(　*　G　)　.　vertices　[　(　*　G　)　.　vexnum　]　.　data　,　v　)　;　(　*　G　)　.　vertices　[　(　*　G　)　.　vexnum　]　.　firstarc　=　NULL　;　(　*　G　)　.　vexnum　删除顶点的算法　Status　DeleteVex　(　ALGraph　*　G　,　VertexType　v　)　{　int　i　,　j　;　ArcNode　*　p　,　*　q　;　j　=　LocateVex　(　*　G　,　v　)　;　if　(　j　<　0　)　return　ERROR　;　p　=　(　*　G　)　.　vertices　[　j　]　.　firstarc　;　while　(　p　)　{　q　=　p　;　p　=　p　->　nextarc　;　if　(　(　*　G　)　.　kind　%　2　)　free　(　q　->　info　)　;　free　(　q　)　;　(　*　G　)　.　arcnum　G　)　.　vexnum　--　;　for　(　i　=　j　;　i　<　(　*　G　)　.　vexnum　;　i　G　)　.　vertices　[　i　]　=　(　*　G　)　.　vertices　[　i　+　1　]　;　}　for　(　i　=　0　;　i　<　(　*　G　)　.　vexnum　;　i　++　)　{　p　=　(　*　G　)　.　vertices　[　i　]　.　firstarc　;　while　(　p　)　{　if　(　p　->　adjvex　==　j　)　{　if　(　p　==　(　*　G　)　.　vertices　[　i　]　.　firstarc　)　{　(　*　G　)　.　vertices　[　i　]　.　firstarc　=　p　->　nextarc　;　if　(　(　*　G　)　.　kind　%　2　)　free　(　p　->　info　)　;　free　(　p　)　;　p　=　(　*　G　)　.　vertices　[　i　]　.　firstarc　;　if　(　(　*　G　)　.　kind　<　2　)　(　*　G　)　.　arcnum　--　;　}　else　{　q　->　nextarc　=　p　->　nextarc　;　if　(　(　*　G　)　.　kind　%　2　)　free　(　p　->　info　)　;　free　(　p　)　;　p　=　q　->　nextarc　;　if　(　(　*　G　)　.　kind　<　2　)　(　*　G　)　.　arcnum　else　{　if　(　p　->　adjvex　>　j　)　p　->　adjvex　--　;　q　=　p　;　p　=　p　->　nextarc　;　}　}　}　return　OK　;　}　//插入新弧的算法　Status　InsertArc　(　ALGraph　*　G　,　VertexType　v　,　VertexType　w　)　{　ArcNode　*　p　;　int　w1　,　i　,　j　;　i　=　LocateVex　(　*　G　,　v　)　;　j　=　LocateVex　(　*　G　,　w　)　;　if　(　j　<　0　||　i　<　0　)　return　ERROR　;　(　*　G　)　.　arcnum　++　;　if　(　(　*　G　)　.　kind　%　2　)　{　printf　(　"请输入弧(边)%s->%s的权值"　,　v　,　w　)　;　scanf　(　"%d"　,　&　w1　)　;　}　p　=　(　ArcNode　*　)　malloc　(　sizeof　(　ArcNode　)　)　;　p　->　adjvex　=　j　;　if　(　(　*　G　)　.　kind　%　2　)　{　p　->　info　=　(　int　*　)　malloc　(　sizeof　(　int　p　->　info　)　=　w1　;　}　else　p　->　info　=　NULL　;　p　->　nextarc　=　(　*　G　)　.　vertices　[　i　]　.　firstarc　;　(　*　G　)　.　vertices　[　i　]　.　firstarc　=　p　;　if　(　(　*　G　)　.　kind　>=　2　)　{　p　=　(　ArcNode　*　)　malloc　(　sizeof　(　ArcNode　)　)　;　p　->　adjvex　=　i　;　if　(　(　*　G　)　.　kind　==　3　)　{　p　->　info　=　(　int　*　)　malloc　(　sizeof　(　int　p　->　info　)　=　w1　;　}　else　p　->　info　=　NULL　;　p　->　nextarc　=　(　*　G　)　.　vertices　[　j　]　.　firstarc　;　(　*　G　)　.　vertices　[　j　]　.　firstarc　=　p　;　}　return　OK　;　}　//删除弧的算法　Status　DeleteArc　(　ALGraph　*　G　,　VertexType　v　,　VertexType　w　)　{　ArcNode　*　p　,　*　q　;　int　i　,　j　;　i　=　LocateVex　(　*　G　,　v　)　;　j　=　LocateVex　(　*　G　,　w　)　;　if　(　j　<　0　||　i　<　0　)　return　ERROR　;　p　=　(　*　G　)　.　vertices　[　i　]　.　firstarc　;　while　(　p　&&　p　->　adjvex　!=　j　)　{　q　=　p　;　p　=　p　->　nextarc　;　}　if　(　p　&&　p　->　adjvex　==　j　)　{　if　(　p　==　(　*　G　)　.　vertices　[　i　]　.　firstarc　)　(　*　G　)　.　vertices　[　i　]　.　firstarc　=　p　->　nextarc　;　else　q　->　nextarc　=　p　->　nextarc　;　if　(　(　*　G　)　.　kind　%　2　)　free　(　p　->　info　)　;　free　(　p　)　;　(　*　G　)　.　arcnum　--　;　}　if　(　(　*　G　)　.　kind　>=　2　)　{　p　=　(　*　G　)　.　vertices　[　j　]　.　firstarc　;　while　(　p　&&　p　->　adjvex　!=　i　)　{　q　=　p　;　p　=　p　->　nextarc　;　}　if　(　p　&&　p　->　adjvex　==　i　)　{　if　(　p　==　(　*　G　)　.　vertices　[　j　]　.　firstarc　)　(　*　G　)　.　vertices　[　j　]　.　firstarc　=　p　->　nextarc　;　else　q　->　nextarc　=　p　->　nextarc　;　if　(　(　*　G　)　.　kind　==　3　)　free　(　p　->　info　)　;　free　(　p　)　;　}　}　return　OK　;　}　//图的销毁算法　void　DestroyGraph　(　ALGraph　*　G　)　{　int　i　;　ArcNode　*　p　,　*　q　;　(　*　G　)　.　vexnum　=　0　;　(　*　G　)　.　arcnum　=　0　;　for　(　i　=　0　;　i　<　(　*　G　)　.　vexnum　;　i　++　)　{　p　=　(　*　G　)　.　vertices　[　i　]　.　firstarc　;　(　*　G　)　.　vertices　[　i　]　.　firstarc　=　NULL　;　while　(　p　)　{　q　=　p　->　nextarc　;　if　(　(　*　G　)　.　kind　%　2　)　free　(　p　->　info　)　;　free　(　p　)　;　p　=　q　图的创建算法　Status　CreateGraph　(　ALGraph　*　G　)　{　FILE　*　fp　;　int　i　,　j　,　k　;　int　w　;　VertexType　va　,　vb　;　ArcNode　*　p　;　if　(　(　fp　=　fopen　(　"有向图.txt"　,　"r"NULL　)　{　printf　(　"打开失败!\n"　)　;　exit　(　0　)　;　}　else　printf　(　"打开文件成功\n"　)　;　printf　(　"请输入图的类型(有向图:0,有向网:1,无向图:2,无向网:3)scanf("%d",&(*G).kind);　fscanf　(　fp　,　"%d"　,　&　G　->　kind　)　;　printf　(　"%d\n"　,　G　->　kind　)　;　printf　(　"请输入图的顶点数,边数:scanf("%d,%d",&(*G).vexnum,&(*G).arcnum);　fscanf　(　fp　,　"%d,%d"　,　&　G　->　vexnum　,　&　G　->　arcnum　)　;　printf　(　"%d,%d\n"　,　(　*　G　)　.　vexnum　,　(　*　G　)　.　arcnum　)　;　printf　(　"请输入%d个顶点的值(<%d个字符):\n"　,　(　*　G　)　.　vexnum　,　MAX_NAME　)　;　for　(　i　=　0　;　i　<　(　*　G　)　.　vexnum　;　++　i　)　{　//scanf("%s",(*G).vertices[i].data);　fscanf　(　fp　,　"%s"　,　&　G　->　vertices　[　i　]　.　data　)　;　printf　(　"%s　"　,　G　->　vertices　[　i　]　.　data　)　;　(　*　G　)　.　vertices　[　i　]　.　firstarc　=　NULL　;　}　printf　(　"\n"　)　;　if　(　(　*　G　)　.　kind　==　1　||　(　*　G　)　.　kind　==　3　)　printf　(　"请顺序输入每条弧(边)的权值、弧尾和弧头(以空格作为间隔):\n"　)　;　else　printf　(　"请顺序输入每条弧(边)的弧尾和弧头(以空格作为间隔):\n"　)　;　for　(　k　=　0　;　k　<　(　*　G　)　.　arcnum　;　++　k　)　{　if　(　(　*　G　)　.　kind　==　1　||　(　*　G　)　.　kind　==　3　)　{　//scanf("%d%s%s",&w,va,vb);　fscanf　(　fp　,　"%d%s%s"　,　&　w　,　va　,　vb　)　;　printf　(　"%d%s%s"　,　w　,　va　,　vb　)　;　}　else　{　//scanf("%s%s",va,vb);　fscanf　(　fp　,　"%s%s"　,　va　,　vb　)　;　printf　(　"%s　%s"　,　va　,　vb　)　;　}　printf　(　"\n"　)　;　i　=　LocateVex　(　*　G　,　va　)　;　j　=　LocateVex　(　*　G　,　vb　)　;　p　=　(　ArcNode　*　)　malloc　(　sizeof　(　ArcNode　)　)　;　p　->　adjvex　=　j　;　if　(　(　*　G　)　.　kind　==　1　||　(　*　G　)　.　kind　==　3　)　{　p　->　info　=　(　int　*　)　malloc　(　sizeof　(　int　p　->　info　)　=　w　;　}　else　p　->　info　=　NULL　;　p　->　nextarc　=　(　*　G　)　.　vertices　[　i　]　.　firstarc　;　(　*　G　)　.　vertices　[　i　]　.　firstarc　=　p　;　if　(　(　*　G　)　.　kind　>=　2　)　{　p　=　(　ArcNode　*　)　malloc　(　sizeof　(　ArcNode　)　)　;　p　->　adjvex　=　i　;　if　(　(　*　G　)　.　kind　==　3　)　{　p　->　info　=　(　int　*　)　malloc　(　sizeof　(　int　p　->　info　)　=　w　;　}　else　p　->　info　=　NULL　;　p　->　nextarc　=　(　*　G　)　.　vertices　[　j　]　.　firstarc　;　(　*　G　)　.　vertices　[　j　]　.　firstarc　=　p　;　}　}　fclose　(　fp　)　;　printf　(　"图已创建完毕!\n"　)　;　return　OK　;　}　//图的打印输出　void　Display　(　ALGraph　G　)　{　int　i　;　ArcNode　*　p　;　switch　(　G　.　kind　)　{　case　DG　:　printf　(　"有向图\n"　)　;　break　;　case　DN　:　printf　(　"有向网\n"　)　;　break　;　case　AG　:　printf　(　"无向图\n"　)　;　break　;　case　AN　:　printf　(　"无向网\n"　)　;　}　printf　(　"%d个顶点:\n"　,　G　.　vexnum　)　;　for　(　i　=　0　;　i　<　G　.　vexnum　;　i　++　)　printf　(　"%s　"　,　G　.　vertices　[　i　]　.　data　)　;　printf　(　"\n%d条弧(边):\n"　,　G　.　arcnum　)　;　for　(　i　=　0　;　i　<　G　.　vexnum　;　i　++　)　{　p　=　G　.　vertices　[　i　]　.　firstarc　;　while　(　p　)　{　if　(　G　.　kind　<=　1　)　{　printf　(　"%s->%s　"　,　G　.　vertices　[　i　]　.　data　,　G　.　vertices　[　p　->　adjvex　]　.　data　)　;　if　(　G　.　kind　==　DN　)　printf　(　":%d　"　,　*　(　p　->　info　)　)　;　}　else　{　if　(　i　<　p　->　adjvex　)　{　printf　(　"%s->%s　"　,　G　.　vertices　[　i　]　.　data　,　G　.　vertices　[　p　->　adjvex　]　.　data　)　;　if　(　G　.　kind　==　AN　)　printf　(　":%d　"　,　*　(　p　->　info　p　=　p　->　nextarc　;　}　printf　(　"\n"void　menu　(　)　{　printf　(　"\t\t\t\t\t|n"　)　;　printf　(　"\t\t\t\t\t||　图的邻接表存储结构　||\n"　)　;　printf　(　"\t\t\t\t\t|n"　)　;　printf　(　"\t\t\t\t\t||　1.求顶点位置　||\n"　)　;　printf　(　"\t\t\t\t\t|n"　)　;　printf　(　"\t\t\t\t\t||　2.求顶点信息　||\n"　)　;　printf　(　"\t\t\t\t\t|n"　)　;　printf　(　"\t\t\t\t\t||　3.对顶点赋新值　||\n"　)　;　printf　(　"\t\t\t\t\t|n"　)　;　printf　(　"\t\t\t\t\t||　4.求顶点的第一个邻接顶点序号　||\n"　)　;　printf　(　"\t\t\t\t\t|n"　)　;　printf　(　"\t\t\t\t\t||　5.求顶点v相对于某顶点w的下一个邻接顶点序号　||\n"　)　;　printf　(　"\t\t\t\t\t|n"　)　;　printf　(　"\t\t\t\t\t||　6.插入新顶点　||\n"　)　;　printf　(　"\t\t\t\t\t|n"　)　;　printf　(　"\t\t\t\t\t||　7.删除顶点　||\n"　)　;　printf　(　"\t\t\t\t\t|n"　)　;　printf　(　"\t\t\t\t\t||　8.插入新弧　||\n"　)　;　printf　(　"\t\t\t\t\t|n"　)　;　printf　(　"\t\t\t\t\t||　9.删除弧　||\n"　)　;　printf　(　"\t\t\t\t\t|n"　)　;　printf　(　"\t\t\t\t\t||　10.销毁图　||\n"　)　;　printf　(　"\t\t\t\t\t|n"　)　;　printf　(　"\t\t\t\t\t||　0.退出　||\n"　)　;　printf　(　"\t\t\t\t\t|n"　)　;　}　int　main　(　void　)　{　int　i　,　k　;　ALGraph　g　;　VertexType　a　,　b　;　CreateGraph　(　&　g　)　;　Display　(　g　)　;　while　(　1　)　{　menu　(　)　;　printf　(　"请选择图的相关操作:"　)　;　scanf　(　"%d"　,　&　i　)　;　switch　(　i　)　{　case　1　:　printf　(　"请输入待求的顶点:\n"　)　;　scanf　(　"%s"　,　a　)　;　k　=　LocateVex　(　g　,　a　)　;　printf　(　"顶点%s的位置是%d\n"　,　a　,　k　)　;　break　;　case　2　:　printf　(　"请输入待求的顶点序号:\n"　)　;　scanf　(　"%d"　,　&　k　)　;　GetVex　(　g　,　k　)　;　break　;　case　3　:　printf　(　"请输入待赋值顶点和所赋新值:\n"　)　;　scanf　(　"%s　%s"　,　a　,　b　)　;　PutVex　(　&　g　,　a　,　b　)　;　printf　(　"赋值成功!\n"　)　;　break　;　case　4　:　printf　(　"请输入待求顶点:\n"　)　;　scanf　(　"%s"　,　a　)　;　k　=　FirstAdjVex　(　g　,　a　)　;　printf　(　"顶点%s的第一个邻接顶点的序号为:%d\n"　,　a　,　k　)　;　break　;　case　5　:　printf　(　"请输入顶点1与顶点2:\n"　)　;　scanf　(　"%s　%s"　,　a　,　b　)　;　k　=　NextAdjVex　(　g　,　a　,　b　)　;　printf　(　"顶点%s相对于顶点%s的下一个邻接顶点的序号是:%d\n"　,　a　,　b　,　k　)　;　break　;　case　6　:　printf　(　"请输入待插入的顶点:\n"　)　;　scanf　(　"%s"　,　a　)　;　InsertVex　(　&　g　,　a　)　;　printf　(　"插入成功,如下图所示!\n"　)　;　Display　(　g　)　;　break　;　case　7　:　printf　(　"请输入待删除的顶点:\n"　)　;　scanf　(　"%s"　,　a　)　;　DeleteVex　(　&　g　,　a　)　;　printf　(　"删除成功,如下图所示!\n"　)　;　Display　(　g　)　;　break　;　case　8　:　printf　(　"请输入待插入弧的顶点:\n"　)　;　scanf　(　"%s　%s"　,　a　,　b　)　;　InsertArc　(　&　g　,　a　,　b　)　;　printf　(　"插入成功!"　)　;　Display　(　g　)　;　break　;　case　9　:　printf　(　"请输入待删除弧的顶点:\n"　)　;　scanf　(　"%s　%s"　,　a　,　b　)　;　DeleteArc　(　&　g　,　a　,　b　)　;　printf　(　"删除成功!"　)　;　Display　(　g　)　;　break　;　case　10　:　DestroyGraph　(　&　g　)　;　break　;　case　0　:　exit　(　0　)　;　default　:　printf　(　"输入错误!\n"　)　;　break