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
请按任意键继续. . .