16-Estructura de almacenamiento de gráficos de estructura de datos

Introducción: Principalmente para almacenamiento secuencial y almacenamiento en cadena de gráficos. Entre ellos, el almacenamiento secuencial se refiere al método de dibujo y código de la matriz de adyacencia. La matriz de adyacencia se divide en un gráfico ponderado y un gráfico no ponderado. La diferencia es que el lugar con datos completa el valor de peso y el lugar sin datos se puede completar con 0 o ∞, mientras que el gráfico ponderado y el gráfico no ponderado Los gráficos de peso se subdividen en gráficos dirigidos y gráficos no dirigidos. Un gráfico no dirigido es una matriz simétrica porque no hay dirección alguna y el grado de salida y de entrada son los mismos. Existen diferencias en los gráficos dirigidos: por cierto, la matriz de adyacencia es el grado exterior cuando se ve horizontalmente y el grado interior cuando se ve verticalmente. El almacenamiento vinculado incluye lista de adyacencia, lista entrecruzada y lista múltiple de adyacencia, entre las cuales están disponibles la lista de adyacencia, el gráfico dirigido y el gráfico no dirigido, y la lista entrecruzada es una optimización de su gráfico dirigido por lista de adyacencia, que puede calcular el -grado y grado exterior al mismo tiempo, y la tabla múltiple de adyacencia es una optimización del gráfico no dirigido de la tabla de adyacencia, que puede ahorrar la mitad del espacio de borde, desde el número original de vértices + 2 * número total de bordes hasta el número de vértices + el número total de aristas.

Tabla de contenido

1. Almacenamiento secuencial: matriz de adyacencia

1.1 Introducción

1.2-Código

1.3-Resultados de la operación

2. Lista de adyacencia de almacenamiento vinculada

2.1 Lista de adyacencia

2.1.1 Código

2.2 Lista de enlaces cruzados

2.2.1 Código

2.3 Adyacencia de varias tablas

2.3.1 Código:


1. Almacenamiento secuencial: matriz de adyacencia

1.1 Introducción

Los gráficos incluyen naturalmente vértices y aristas. La matriz de adyacencia representa un gráfico en forma de matriz.

Entre ellos, se necesita una matriz unidimensional para almacenar la información de los vértices; los vértices son una unidad como el estudiante 1, el estudiante 2 y similares.

También se necesita una matriz bidimensional, que es una matriz de adyacencia, para almacenar la relación entre los vértices; en segundo lugar, es un registro, el número de vértices y el número total de aristas en el gráfico.

La idea de mi código es mía, desde la creación hasta la operación, si encuentro una simple, la cambiaré más tarde.

Idea:

  1. Primero inicialice el gráfico e ingrese el número deseado de vértices y aristas en el gráfico. En segundo lugar, inicialice la matriz unidimensional y la matriz bidimensional.
  2. Para crear e ingresar datos, primero proporcione la información del vértice e ingrésela en la matriz de vértices. El siguiente paso es juzgar si se trata de un gráfico dirigido o no dirigido. (El valor predeterminado es un mapa no autorizado) (Un mapa autorizado es solo un conjunto adicional de números que deben ingresarse manualmente).
  3. Un gráfico no dirigido es una matriz simétrica. Si ingresa la relación de borde deseada, es decir, 1 y 2, la matriz de adyacencia correspondiente se cambiará directamente a 1, lo que indica que los dos puntos están conectados y la posición simétrica también será actualizado a 1.
  4. Gráfico dirigido. Simplemente actualice uno, pero no el otro.

1.2-Código

#include <stdio.h>
#define Max 10
#include <string.h>
//图的顺序存储_邻接矩阵
typedef struct
{
	char vertex[Max];    //存放顶点的一维数组 
	int  edge[Max][Max];	//表示顶点之间关系的二维数组; 
	
	int vertex_num;  //顶点数 
	int edge_num;    //边数 
	
}MGragh; 
//初始化邻接矩阵 
void InitMGragh(MGragh *a) 
{
	printf("添加几个顶点\n");
	int x;
	scanf("%d",&x); 
	//赋值	
	a->vertex_num=x;
	
	printf("有多少条边\n"); 
	int c; 
	scanf("%d",&c);
	//赋值 
	a->edge_num=c;
	//初始化邻接矩阵存储边信息的二维数组 
	a->edge[Max][Max];
	int p,q;
	for(p=0;p<a->vertex_num;p++)
	{
		for(q=0;q<a->vertex_num;q++)
		{
			a->edge[p][q]=0;
		}
	} 
	//初始化,顶点数组 
	a->vertex[a->vertex_num]='0'; 	
}
//打印邻接矩阵 
void PrintMGragh(MGragh *a)
{
	int p,q;
		for(p=0;p<a->vertex_num;p++)
		{
			for(q=0;q<a->vertex_num;q++)
			{
				
				printf("%d ",a->edge[p][q]);
			}
			printf("\n");
		} 
}
void Creat_MGragh(MGragh *a)
{
	printf("图的顶点数%d\n",a->vertex_num);
	int i=0;
	printf("请加顶点到顶点数组\n"); 
	for(i=0;i<a->vertex_num;i++)
	{	printf("i=%d\n",i);
		char x;
		x=getchar();
		char k;//由于单个字符输入,回车也在输入序列中,因此还需要一个变量,来吃掉回车 
		k=getchar();
		a->vertex[i]=x;
	}
	printf("您想弄成无向图还是有向图,1为无向图,2为有向图\n");
	int text;
	scanf("%d",&text);
	if(text == 1)
	{
		printf("请添加顶点间关系\n"); 
		
		int w=0;
		while(w!=2)
		{
			printf("哪个顶点和哪个顶点之间有联系\n");
			int d1,d2;
			scanf("%d %d",&d1,&d2);
			a->edge[d1-1][d2-1]=1;
			a->edge[d2-1][d1-1]=1;
			printf("是否还需要继续添加,是填1,否填2\n");
			scanf("%d",&w); 
		}		
	}
	else
	{
		printf("请添加顶点间关系\n"); 
		
		int w=0;
		while(w!=2)
		{
			int d1,d2;
			printf("从哪个顶点到哪个顶点\n");
			scanf("%d %d",&d1,&d2);
			a->edge[d1-1][d2-1]=1;
			printf("是否还需要继续添加,是填1,否填2\n");
			scanf("%d",&w); 
		}
	} 
}

int main()
{
	MGragh a;
	//初始化图 
	InitMGragh(&a);
	//创建邻接矩阵图 
	Creat_MGragh(&a); 
	//打印邻接矩阵 
	PrintMGragh(&a);
	return 0;
 } 

1.3-Resultados de la operación

2. Lista de adyacencia de almacenamiento vinculada

2.1 Lista de adyacencia

        Introducción: la lista de adyacencia es en realidad principalmente una lista de vértices seguida de una lista de bordes correspondiente. Registre el número total de aristas y vértices.

Para almacenamiento en cadena. Es adecuado para gráficos dispersos y conveniente para calcular el grado: solo necesita encontrar el vértice correspondiente y luego atravesar la cadena a través de la lista enlazada individualmente de vértices. Pero el grado requiere atravesar cada vértice de la lista enlazada individualmente.

Se aceptan gráficos dirigidos y no dirigidos . En un gráfico dirigido , si cada vértice pasa por una dirección, sale en grados o entra en grados. Por lo tanto, el espacio que requiere es O (número de vértices + número total de aristas); y están conectados a los vértices y todos están conectados, por lo que el espacio de almacenamiento requerido es O (número de vértices + 2 * aristas totales) ).

2.1.1 Código

        ArcNode de la tabla de borde: incluye el subíndice del punto y el campo del siguiente puntero.

//边表 
typedef struct ArcNode
{
	int NodeName;
	struct ArcNode *next;
	
}ArcNode; 

         Tabla de vértices: almacena cada vértice del gráfico. Detrás de cada vértice hay en realidad una lista enlazada individualmente de los grados externos correspondientes a partir de él.

//顶点表
typedef struct
{
	int data;//顶点内容 
	ArcNode* first;	//顶点标的链的头指针 
	
}VNode;

        Lista de adyacencia: La última es la lista de adyacencia, es decir, solo es necesario recorrer la tabla de vértices para acceder al grado exterior de cada vértice.

//创建邻接表,包含顶点表和边表,以及边数和顶点数的记录 
typedef struct
{
	VNode vertice[vertice_num];//顶点表,每个顶点标中的数据,串成一个对应的链 
	int vexnum;//顶点数 
	int edgenum;//边数	
}ALGragh; 

       Debido a la implementación, en mi nivel actual, se siente un poco problemático. Necesito atravesar cada vértice, y cada vértice necesita crear un nodo de tabla de borde. También necesito darle a cada vértice una única lista enlazada para formar. No tengo idea en este momento y me quedo atascado en medio de la escritura. Bien, una vez que lo domines, puedes implementarlo nuevamente.        

2.2 Lista de enlaces cruzados

        Introducción: la lista de enlaces cruzados solo es aplicable a gráficos dirigidos. Para compensar el gráfico dirigido en la lista de adyacencia, solo se pueden calcular grados unidireccionales.

Hay información más detallada. Primero, proporcione la forma de la lista de adyacencia y dibuje el grado de salida. Luego encuentre el grado de entrada de cada vértice en la tabla de vértices. Si el grado de entrada ingresa 0, comience desde 0 y observe qué punto final en la tabla de borde es 0. Conéctelos. Si no, configúrelos para que estén vacíos.

        La lista entrecruzada todavía atraviesa la cadena de grado exterior y la cadena de grado interior del vértice correspondiente a través de la tabla de vértices, y puede alcanzar el grado exterior y interior del vértice correspondiente.

2.2.1 Código

//边表
typedef struct ArcNode
{
	int tailvex,headvex;//弧尾tail弧头head     弧尾(起点)->弧头(终点) 
	struct ArcNode *hlink,*tlink;//指针域,即出度指针域为弧头,入读指针域为弧尾,先连接弧头指针域,出度、再连接弧尾指针域 
	char info;//存储信息的指针 
}ArcNode; 
//顶点表
typedef struct VNode
{
	AreNode *firstin,*firstout;//出度入读头指针 
	int data;//顶点信息 
	
}VNode;
//十字链表
typedef struct GLGraph 
{
	VNode xlist[vertice_num];//顶点表 
	int vexnum,edgenum;//顶点数和边数 
	
}GLGraph;  

2.3 Adyacencia de varias tablas

Introducción: La lista múltiple de adyacencia solo es aplicable a gráficos no dirigidos. Es una optimización del gráfico no dirigido en la lista de adyacencia. El gráfico no dirigido en la lista de adyacencia repetirá múltiples conexiones, 2 * el número total de bordes y la adyacencia múltiple lista guardada, que es E.

Método de dibujo: primero dibuje la tabla de vértices y la tabla de bordes. La tabla de bordes contiene los vértices relacionados con los vértices en la tabla de vértices más a la izquierda, es decir, los bordes. Es el punto inicial y el punto final del borde, y tiene dos campos de puntero relacionados. El primer paso es marcar primero los valores correspondientes, dibujar de arriba a abajo, y los vértices inferiores, si hay aristas repetidas, no dibujar.

//Ejemplo de organización fuerte y conectada: no quiero dibujarla yo mismo, solo sé perezoso

El segundo paso es encadenar. Comenzando desde el vértice en la tabla de vértices de la izquierda, busque el campo de puntero que sea el mismo que el vértice en la tabla del borde derecho y conéctelo. Por ejemplo, el subíndice de b es 2. A partir de b , encuentra el borde derecho El campo del puntero de 2 en la tabla. Hay un campo de puntero en la primera línea de 2 y dos en la segunda línea, simplemente encadene estos tres.

2.3.1 Código:

//邻接多重表-无向图
//边表
typedef struct AreNode
{
		int mark; //标记是否串过
		int ivex,jvex;//表示弧的两个顶点
		struct AreNode *ilink,*jlink;
		char info;//其他信息	
}AreNode;
//顶点表
typedef struct VNode
{
	int data;//顶点信息 
	AreNode *first;//指向边表中第一个挨着该顶点的结点 
	
}VNode;
//邻接多重表
typedef struct  AMLGraph
{
	VNode xlist[vertice_num];//顶点表 
	int vexnum,edgenum;//总边数和总结点数 
}AMLGraph; 

Supongo que te gusta

Origin blog.csdn.net/m0_59844149/article/details/132678679
Recomendado
Clasificación