数据结构——图-有向带权图的邻接表

在这里插入图片描述
在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

#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;
}
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值