数据结构 c语言实现无向图邻接多重表的建立、插入、删除

ps:

1.部分内容我设置了隐藏,点赞后可以查看全部内容哦
2.仅供参考,请勿抄袭,特别当这内容也是你本周的作业时
3.代码可能存在错误,希望大佬能给我指出问题

题目如下

在这里插入图片描述

开始有点后悔来北邮了,天天敲代码头发掉了好多
这次的内容主要难点在删除吧,因为邻接多重表的结构,每个结点都有两个指针指向他
所以要分别找到这两个结点,让他们的后续指针跳过删除的结点

下面直接上代码吧

#include<stdio.h>
#include<stdlib.h>
#define MAX_VERTEX_NUM 20//最大顶点数 
#define VRType int 
#define VertexType int
#define OK 0
#define ERROR -1
typedef enum{unvisited,visited
} Visitlf;//是否访问过的标志 
typedef struct Ebox{	//	边结构 
	Visitlf mark;//访问标记
	int ivex,jvex; //两个顶点位置
	struct Ebox *ilink,*jlink;//指向依附于顶点的下一条边 
	VRType weight;//边的权值 
}Ebox;

typedef struct VexBox{	//	顶点结构
	 VertexType data;//顶点值 
	 Ebox *firstedge;//指向第一条依附于该顶点的边 
}VexBox;
typedef struct{	//	多重链表结构
	VexBox adjmulist[MAX_VERTEX_NUM];
	int vexnum,edgenum;//顶点数和边数 
}AMLGraph;

int LocateVex(AMLGraph g,int v)
{	int num;
	for(num=0;num<g.vexnum;num++)
	{	if(v==g.adjmulist[num].data)
		return num;
	}
	return -1;

}

void CreateGraph(AMLGraph *g)
{	int i,j,k,vi,vj,aweight;
	Ebox *p; 
	printf("请输入图的顶点数和边数:");
	scanf("%d %d",&g->vexnum,&g->edgenum);
	printf("请依次输入顶点的值:\n");
	for(i=0;i<g->vexnum;i++)
	{	printf("请输入第%d个顶点的值:",i+1); 
		scanf("%d",&g->adjmulist[i].data);
		g->adjmulist[i].firstedge=NULL;
	}
	printf("请依次输入边的信息:\n");
	for(k=0;k<g->edgenum;k++) 
	{	scanf("%d %d %d",&vi,&vj,&aweight);//得到边的两个端点的值和权值 
		i=LocateVex(*g,vi);
		j=LocateVex(*g,vj);//确定两个端点在g中的位置 
		p=(Ebox *)malloc(sizeof(Ebox));
		if(!p)
		exit(1);
		p->mark=unvisited;
		p->ivex=i;
		p->jvex=j;
		p->weight=aweight;
		p->ilink=g->adjmulist[i].firstedge;
		g->adjmulist[i].firstedge=p;
		p->jlink=g->adjmulist[j].firstedge;
		g->adjmulist[j].firstedge=p;
	}
	
}
int InsertVex(AMLGraph *g,VertexType adata)
{	
	if(g->vexnum==MAX_VERTEX_NUM)
	return ERROR;
	int i=g->vexnum;
	g->adjmulist[i].data=adata;
	g->adjmulist[i].firstedge=NULL;
	g->vexnum++;
	return OK;
}
int InsertArc(AMLGraph *g,int vi,int vj,VRType aweight)
{	int i,j;
	Ebox *p; 
	i=LocateVex(*g,vi);
	j=LocateVex(*g,vj);
	if(i<0||j<0)
		return ERROR;
	p=(Ebox *)malloc(sizeof(Ebox));
		if(!p)
		exit(1);
		p->mark=unvisited;
		p->ivex=i;
		p->jvex=j;
		p->weight=aweight;
		p->ilink=g->adjmulist[i].firstedge;
		g->adjmulist[i].firstedge=p;
		p->jlink=g->adjmulist[j].firstedge;
		g->adjmulist[j].firstedge=p;
		g->edgenum++;
		return OK;
	
}
void Visit(Ebox *p,AMLGraph g)
{	if(!p)
	return;
	Visit(p->jlink,g);
	Visit(p->ilink,g);
	if(p->mark==unvisited)
	{	p->mark=visited;
		printf("(%d,%d)权值为%d\n",g.adjmulist[p->ivex].data,g.adjmulist[p->jvex].data,p->weight);
	}

}
int DeleteArc(AMLGraph *g,VertexType v,VertexType w)
{	int i,j;
	Ebox *p,*q;
	i=LocateVex(*g,v);
	j=LocateVex(*g,w);//判断端点位置
	if(i<0||j<0)//端点不存在 
		return ERROR; 
	//对于一条弧,有两个指针指向他,需要依次删除
	
	p=g->adjmulist[i].firstedge;
	//若首条边就是要删除的边
	if(p!=NULL&&p->jvex==j)
		g->adjmulist[i].firstedge=p->ilink;
	else if(p!=NULL&&p->ivex==j)
		g->adjmulist[i].firstedge=p->jlink;
		//首条边不是要删除的边 
	else
		{while(p!=NULL)
			{if(p->ivex==i&&p->jvex!=j)//i相等,j不等,找i的下一个 
				{	q=p;
					p=p->ilink;
				 }
			else if(p->jvex==i&&p->ivex!=j) //j相等,i不等,找i的下一个
			{	q=p;
				p=p->jlink;
			}
			else
				break;
			}
		}
		if(!p) 	
			return ERROR;
		if(p->ivex==i&&p->jvex==j)
			{
			if(q->ivex==i)
	 			q->ilink=p->ilink;
	 		else
	 			q->jlink=p->ilink;
	 		}
	 	else if(p->ivex==j&&p->jvex==i)
		 	{	if(q->ivex==i)
		 		q->ilink=p->jlink;
		 		else
		 		q->jlink=p->jlink;
			 }
	//从另一指针删除 
	p=g->adjmulist[j].firstedge;
	if(p&&p->jvex==i)
	{	g->adjmulist[j].firstedge=p->ilink;
	 }
	else if(p&&p->ivex==i) 
	{	
		g->adjmulist[j].firstedge=p->jlink;
	 }
	 else
	 {
	 	while(p!=NULL)
	 	{	if(p->ivex==j&&p->jvex!=i)
	 		{	q=p;
	 			p=p->ilink;
			 }
			else if(p->jvex==j&&p->ivex!=i)
			{	q=p;
				p=p->jlink;
			}
			else
			{	break;
			}
		 }
		 if(p->ivex==i&&p->jvex==j)
		 {	if(q->ivex==j)
		 	q->ilink=p->jlink;
		 	else
		 	q->jlink=p->jlink;
		 	free(p);
		 }
		 else if(p->ivex==j&&p->jvex==i)
		 {	if(q->ivex==j)
		 	q->ilink=p->ilink;
		 	else
		 	q->jlink=p->ilink;
		 	free(p);
		 }
	 	
	 }
	 g->edgenum--;
	 return OK	;
}
int DeleteVex(AMLGraph *g,VertexType v)
{	int i;
	int j;
	Ebox *p;
	i=LocateVex(*g,v);
	if(i<0)
		return ERROR;
	for(j=0;j<g->vexnum;j++)
	{	if(j==i)
			continue;
		DeleteArc(g,v,g->adjmulist[j].data);
	}
	for(j=i+1;j<g->vexnum;j++)
	{	g->adjmulist[j-1]=g->adjmulist[j];
	}
	g->vexnum--;
	for(j=i;j<g->vexnum;j++)
	{	p=g->adjmulist[j].firstedge;
		if(p)
		{	if(p->ivex==j+1)
			{	p->ivex--;
				p=p->ilink;
			}
			else
			{	p->jvex--;
				p=p->jlink;
			}
		}
	}
	return OK;
}
void PrintOut(AMLGraph g)
{	Ebox *p;
	int i;
	printf("*******分割线*******\n");
	printf("这个图结构有%d个顶点,%d条边\n",g.vexnum,g.edgenum);
	for(i=0;i<g.vexnum;i++)
	{	printf("第%d个顶点值为:%d\n",i+1,g.adjmulist[i].data);
	}
	printf("这个图结构有以下边:\n");
	for(i=0;i<g.vexnum;i++)
	{	
	p=g.adjmulist[i].firstedge;
		Visit(p,g);
	}
	printf("*******分割线*******\n");
}
int main()
{	AMLGraph test;
	CreateGraph(&test);
	InsertVex(&test,44);
	InsertArc(&test,11,44,999);
	DeleteVex(&test,22);
	PrintOut(test);
}

输出结果

请输入图的顶点数和边数:3 3
请依次输入顶点的值:
请输入第1个顶点的值:11
请输入第2个顶点的值:22
请输入第3个顶点的值:33
请依次输入边的信息:
11 22 5
22 33 6
33 11 7
分割线
这个图结构有3个顶点,2条边
第1个顶点值为:11
第2个顶点值为:33
第3个顶点值为:44
这个图结构有以下边:
(33,11)权值为7
(11,44)权值为999
分割线


Process exited after 9.58 seconds with return value 0
请按任意键继续. . .

  • 85
    点赞
  • 30
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值