图的存储结构之邻接多重表

注:邻接多重表是对无向图的存储结构的优化
具体的概念问题可参考:https://www.cnblogs.com/ssyfj/p/9475148.html

代码实现:

//以下是图的邻接多重表表示法

typedef struct ENode3    //十字链表结点
{
	int ivex, jvex;    //表示两个顶点下标,构成了一条边。
	int weight;            //用于存放权值,对于非网图可以不需要
	struct ENode3* ilink;    //邻接多重表,指向下一个邻接点,
	struct ENode3* jlink;    //邻接多重表,指向下一个邻接点,
}ENode3;

typedef struct VertexNode3   //顶点表结点
{
	VerterType data;    //顶点域,存储顶点信息
	ENode3* firstedge;    //边表头指针
}VertexNode3, AMLList[MAX];

/*图的邻接多重表存储结构*/
typedef struct graph3
{
	AMLList adjList;    //邻接多重表数组

	int numVertexes, numEdges;    //图中所存储的顶点数和边数
}graph3;

extern ENode3* GetNode(graph3* G, int ivex, int jvex);
extern void CreateGraph3(graph3* G);
//根据ivex找到第几行,我们去前面几行查找,jvex获取下标
ENode3* GetNode(graph3* G, int ivex, int jvex)
{
	int i=0;

	ENode3 *e=NULL;

	for (i = ivex - 1; i >= 0; i--)
	{
		e = G->adjList[i].firstedge;

		while (e)
		{
			if (e->jvex == jvex)
			{
				return e;
			}
			e = e->ilink;
		}
	}
	return NULL;
}

void CreateGraph3(graph3* G)
{
	int i=0, j=0, k=0, w=0, flag=0;

	ENode3* e=NULL;

	ENode3* tempNode=NULL;

	printf("please input number of vertex and edge:\n");

	scanf_s("%d,%d", &G->numVertexes, &G->numEdges,4);  //输入顶点数和边数

	getchar();  //获取回车符

	printf("请输入顶点信息:\n");

	//下面的for循环是根据顶点个数实现初始化工作,即输入顶点的信息,并把每个结点的firstedge指针域赋值为NULL
	for (i = 0; i < G->numVertexes; i++)    //输入顶点信息
	{
		scanf_s("%c", &G->adjList[i].data,5);    //输入顶点信息

		G->adjList[i].firstedge = NULL;    //将边表置为空
	}

	getchar();    //可以获取回车符

	//先循环获取边信息。创建所有边信息,放在对应的顶点后面,
	for (k = 0; k < G->numEdges; k++)
	{
		printf("Out-->input edge(vi,vj) vertexs series and the weight:\n");

		scanf_s("%d,%d,%d", &i, &j, &w,4);

		getchar();
		
		e = (ENode3 *)malloc(sizeof(ENode3));//创建邻接多重表结点
		
		//以下四步是给新申请的结点赋初值
		e->ivex = i;

		e->jvex = j;

		e->weight = w;

		e->jlink = NULL;

		//下面两步实现头部插入
		e->ilink = G->adjList[i].firstedge;

		G->adjList[i].firstedge = e;
	}
	//开始连接多张表之间的关系,并且判断ilink和jlink,从第二个顶点开始
	for (i = 1; i < G->numVertexes; i++)
	{
		e = G->adjList[i].firstedge;

		if (e)
		{
			flag = 0;    //用来标识是不是最后一个结点

			while (e&&!flag)    //需要将最后一个单独处理
			{
				if (e->ilink == NULL)
				{
					tempNode = GetNode(G, i, e->ivex);

					e->ilink = tempNode;

					flag = 1;
				}
				tempNode = GetNode(G, i, e->jvex);

				e->jlink = tempNode;

				e = e->ilink;
			}			
		}
		else
		{
			G->adjList[i].firstedge = GetNode(G, i, i);
		}		
	}
}
int main(void)
{
	graph3 gra;
	CreateGraph3(&gra);
	system("pause");
	return 0;
}

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

猜你喜欢

转载自blog.csdn.net/qq_38158479/article/details/104409531