#include <stdio.h>
#include <stdlib.h>
#define VertexType char //顶点的数据类型(char)
#define VertexMax 20 //最大顶点个数 typedef struct ArcNode//边表
{int adjvex;//存储的是该顶点在顶点数组即AdjList[]中的位置int weight; struct ArcNode *next;
}ArcNode;typedef struct VNode //单个顶点
{VertexType vertex;struct ArcNode *firstarc;
}VNode;typedef struct //顶点表
{VNode AdjList[VertexMax];//由顶点构成的结构体数组 int vexnum,arcnum; //顶点数和边数 }ALGraph;int LocateVex(ALGraph *G,VertexType v)
{ int i;for(i=0;i<G->vexnum;i++){if(v==G->AdjList[i].vertex){return i;}}printf("No Such Vertex!\n");return -1;
}void CreateDG(ALGraph *G)
{int i,j;//1.输入顶点数和边数 printf("有向带权图\n"); printf("输入顶点个数和边数:\n");printf("顶点数 n="); scanf("%d",&G->vexnum);printf("边 数 e="); scanf("%d",&G->arcnum);printf("\n\n"); //2.顶点表数据域填值初始化顶点表指针域 printf("输入顶点元素(需要用空格隔开):");for(i=0;i<G->vexnum;i++){scanf(" %c",&G->AdjList[i].vertex);G->AdjList[i].firstarc=NULL;} printf("\n");//3.输入边信息构造邻接表 int n,m;VertexType v1,v2;ArcNode *p1; int value;printf("请输入边的信息(需要用空格隔开)包含边的两端和权值:\n\n"); for(i=0;i<G->arcnum;i++){ //输入边信息,并确定v1和v2在G中的位置,即顶点在AdjList[]数组中的位置(下标) printf("输入第%d条边信息:",i+1); getchar();scanf(" %c %c %d",&v1,&v2,&value);n=LocateVex(G,v1);m=LocateVex(G,v2);if(n==-1||m==-1){printf("NO This Vertex!\n");return;} p1=(ArcNode *)malloc(sizeof(ArcNode));p1->adjvex=m;//填上坐标 p1->weight=value;p1->next=G->AdjList[n].firstarc;//改链(头插法) G->AdjList[n].firstarc=p1;}}
void print(ALGraph G)
{int i;ArcNode *p;printf("\n-------------------------------");printf("\n图的邻接表表示:\n");for(i=0;i<G.vexnum;i++){printf("\n AdjList[%d]%4c",i,G.AdjList[i].vertex);p=G.AdjList[i].firstarc;while(p!=NULL){printf("-->%d权值[%d]",p->adjvex,p->weight);p=p->next;}} printf("\n");
} void InsertVex(ALGraph *G,VertexType v)
{//向邻接表中添加一个新顶点G->AdjList[G->vexnum].vertex=v;G->AdjList[G->vexnum].firstarc=NULL;G->vexnum=G->vexnum+1;
}void InsertArc(ALGraph *G,VertexType v,VertexType w)
{//添加一条新边到邻接表 int value;printf("输入这条边的权值:");scanf("%d",&value);ArcNode *p1; int n,m;n=LocateVex(G,v);m=LocateVex(G,w);p1=(ArcNode *)malloc(sizeof(ArcNode));p1->adjvex=m;//填上坐标 p1->weight=value;p1->next=G->AdjList[n].firstarc;//改链(头插法) G->AdjList[n].firstarc=p1;G->arcnum++;} void DeleteArc(ALGraph *G,VertexType v,VertexType w)
{//删除一条指定的边 int n,m;n=LocateVex(G,v);m=LocateVex(G,w);ArcNode *pre,*p;pre=G->AdjList[n].firstarc;p=pre->next;while(p!=NULL){if(pre->next->adjvex==p->adjvex){pre->next=p->next;free(p);break;}p=p->next;pre=pre->next;}G->arcnum--; }void DeleteVex(ALGraph *G,VertexType v)
{int n;n=LocateVex(G,v);int arcn=0;ArcNode *p;p=G->AdjList[n].firstarc;while(p!=NULL){p=p->next;arcn++;}G->AdjList[n].firstarc=NULL;for(int i=n;i<G->vexnum-1;i++){G->AdjList[i].firstarc=G->AdjList[i+1].firstarc;G->AdjList[i].vertex=G->AdjList[i+1].vertex;}G->vexnum--;G->arcnum=G->arcnum-arcn;} void choice(ALGraph *G)
{int i=0;int j=1;VertexType v,w;printf("[1]:添加的新顶点\n");printf("[2]:添加新边的两端结点\n");printf("[3]:删除边的两端结点\n");printf("[4]:删除的顶点(及其相关联的边)\n");printf("[5]:退出\n");while(j){scanf("%d",&i);switch(i){case 1:printf("输入要添加的新顶点:");getchar();scanf("%c",&v); InsertVex(G,v);print(*G);break;case 2:printf("输入要添加新边的两端结点:");getchar(); scanf("%c %c",&v,&w); InsertArc(G,v, w);print(*G);break;case 3:printf("输入要删除边的两端结点:");getchar();scanf("%c %c",&v,&w); DeleteArc(G,v, w);print(*G);break;case 4:printf("输入要删除的顶点(及其相关联的边):");getchar();scanf("%c",&v); DeleteVex(G,v);print(*G);break;case 5:j=0;break;} }}
int main()
{ALGraph G;CreateDG(&G);print(G);choice(&G);return 0;
}