Implementación de lista de adyacencia de gráfico de estructura de datos

La matriz de adyacencia necesita asignar espacio por adelantado, lo que es fácil de causar un desperdicio de espacio
Además, cuando no hay borde entre dos vértices, la matriz de adyacencia no se puede resolver.

La apariencia de la lista de adyacencia es una combinación del método de almacenamiento de la matriz y la lista vinculada (por supuesto, también puede ser una lista vinculada + una lista vinculada)
una lista de adyacencia en forma de una matriz + una lista vinculada.
Se utiliza una matriz unidimensional para almacenar elementos de vértice, y todos los puntos adyacentes de cada vértice forman una tabla lineal
Inserte la descripción de la imagen aquí
.:

La lista de adyacencia no es única.
Si hay n vértices ye aristas en el gráfico no dirigido, la lista de adyacencia requiere n nodos principales y 2 nodos de tabla. Adecuado para almacenar gráficos dispersos
. El grado del vértice vi en un gráfico no dirigido es el número de nodos en la i-ésima lista enlazada individualmente.
Inserte la descripción de la imagen aquí
Características de la lista de adyacencia:

El grado de salida del vértice vi es el número de nodos en la i-ésima lista enlazada individualmente. El
grado de entrada del vértice vi es el número de nodos en toda la lista enlazada individualmente cuyo valor de dominio de puntos adyacente es i-1 .
Características de la lista de adyacencia inversa:

El grado de entrada del
vértice vi es el número de nodos en la i-ésima lista enlazada individualmente. El grado de salida del vértice vi es el número de nodos en la lista completa enlazada individualmente cuyo valor de dominio de puntos adyacente es i-1

Implementación de gráfico no dirigido

#include<iostream>
using namespace std;
#define MAX 25

typedef char Vertype;
typedef int Edgetype;
typedef int Status;

typedef struct EdgeNode//边表结点  存放每个顶点的邻接点
{
    
    
	int adjvex;//边表下标
	Edgetype weight;//边表权重  若边不存在时即无NULL
	struct EdgeNode *next;//指向下一个邻接点
}EdgeNode;

typedef struct VerNode//顶点表   存放顶点
{
    
    
	Vertype data;//顶点元素
	EdgeNode *firstedge;
}VerNode, AdjList[MAX];//邻接表的 顶点元素 和指向邻点的指针

typedef struct
{
    
    
	AdjList adjList;//邻接表
	int numVer,numEdge;//顶点数目和边的数目
}GraphAdjList;

Status CreatGraph(GraphAdjList &G)
{
    
    
	int i, j, k;
	Edgetype w;
	EdgeNode *e;
	cout << "Enter the number of vertices :"<< endl;
	cin >> G.numVer;
	cout << "Enter the number of Edges :" << endl;
	cin >> G.numEdge;

	cout << "Input vertex content :" << endl;
	for (i = 0; i < G.numVer; i++)
	{
    
    
		cin >> G.adjList[i].data;//输入顶点元素
		G.adjList[i].firstedge = NULL;//初始化邻边表为NULL;
	}

	for (k = 0; k < G.numEdge; k++)
	{
    
    
		cout <<"Enter the vertex number of the edge (Vi, Vj)" << endl;
		cin >> i;
		cin >> j;

		cout << "Enter the weight of edge" << i << "-" << j << endl;
		cin >> w;
		e = new EdgeNode;//将两个顶点相结即可。
		e->adjvex = j;// 邻接序号为j
		e->next = G.adjList[i].firstedge;//i的第一个邻接指针 为e的指针
		e->weight = w;
		G.adjList[i].firstedge = e;


		//有向图则只有生成一次即可
		e = new EdgeNode;
		e->adjvex = i;//无向图 重复一遍
		e->next = G.adjList[j].firstedge;
		G.adjList[j].firstedge = e;
		e->weight = w;
	}
	return 0;
}

//输出无向图
Status DispGraph(GraphAdjList &G)
{
    
    
	int i, j, k;
	cout <<"Output element of ver" << endl;
	for (i = 0; i < G.numVer; i++)
	{
    
    
		cout << G.adjList[i].data << '\t';
	}

	cout << "Output weight"<< endl;
	for (k = 0; k < G.numVer; k++)
	{
    
    
		EdgeNode *p = G.adjList[k].firstedge;//中间指针
		cout <<"xaibiao"<< k <<"constent"<< G.adjList[k].data << "jiedian:" << endl;
		while (p != NULL)
		{
    
    
			cout <<G.adjList[k].data<< "->" << p->adjvex << '\t' << p->weight << '\t' << endl;
			p = p->next;
		}
	}
	/*
	for (k = 0; k < G.numEdge; k++)
	{
		//cout << G.adjList[k].firstedge->adjvex << '\t' << G.adjList[k].firstedge->weight << '\t'<<G.adjList[k].firstedge->next->adjvex<<endl;
		cout << G.adjList[k].firstedge->weight << '\t';
	}
	*/
	return 0;
}
//返回一个顶点的位置 和其邻接表内容
Status OutGraph_x(GraphAdjList &G)
{
    
    
	cout <<"请输入需要找的顶点内容: " << endl;
	Vertype x;
	cin >> x;
	for (int i = 0; i < G.numVer; i++)
	{
    
    
		if(G.adjList[i].data == x)
		{
    
    
			cout << "该元素在图中的位置为: " <<i<<"。  相关邻接表为"<<endl;
			EdgeNode *p = G.adjList[i].firstedge;
			while (p != NULL)
			{
    
    
				cout << p->adjvex << '\t' << p->weight << '\t' << endl;
				p = p->next;
			}
		}
	}
	return 0;
}
//新增一个顶点和对应边
Status AddGraph_x(GraphAdjList &G)
{
    
    
	Vertype x;
	Edgetype edg_num;
	int w;
	int i;
	EdgeNode *p;
	if (G.numVer >= MAX)
	{
    
    
		cout << "Graph memory is full and cannot be expanded "<< endl;
		return NULL;
	}
	else
	{
    
    
		cout << "请输入需要插入的新顶点内容: " << endl;
		cin >> x;
		G.numVer++;
		G.adjList[G.numVer - 1].data = x;//顶点内容赋值
		G.adjList[G.numVer - 1].firstedge = NULL;//顶点指针NULL初始化

		cout << "Please enter the number of new edges" << endl;//新增边的数目
		//如果不成边呢
		cin >> edg_num;
		G.numEdge = G.numEdge+ edg_num;
		p = new EdgeNode;
		for (int j = 0; j < edg_num; j++)
		{
    
    
			cout << "请输入与其成边的顶点位置" << endl;
			cin >> i;
			cout << "请输入权重" << endl;
			cin >> w;

			/*while (p != NULL)
			{
			p = p->next;//找到最后一个结点为空时
			}*/
			//p = new EdgeNode;
			p->adjvex = G.numVer - 1;
			p->next = G.adjList[i].firstedge;
			G.adjList[i].firstedge = p;
			p->weight = w;

			//p = new EdgeNode;
			p->adjvex = i;
			p->next = G.adjList[G.numVer - 1].firstedge;
			G.adjList[G.numVer - 1].firstedge = p;
			p->weight = w;
		}
	}

	return 0;
}
//删除一个顶点  
Status DelGraph_x(GraphAdjList &G)
{
    
    
	Vertype x;
	cout <<"请输入需要删除的顶点:" << endl;
	cin >> x;
	for (int i = 0; i < G.numVer; i++)
	{
    
    
		if (G.adjList[i].data == x)
		{
    
    
			G.adjList[i].data = NULL;//因为是数组类型 其结构必定存在 所以将其置为空
			//free((void *)G.adjList[i].data); //释放顶点
			G.adjList[i].firstedge=NULL;
		}
	}
	return 0;
}
int main()
{
    
    
	GraphAdjList G;
	CreatGraph(G);
	DispGraph(G);
	OutGraph_x(G);
	AddGraph_x(G);
	DispGraph(G);
	DelGraph_x(G);
	DispGraph(G);
	return 0;
}

Inserte la descripción de la imagen aquí

Realización de gráfico dirigido

#include<iostream>
using namespace std;
#define MAX 25

typedef char Vertype;
typedef int Edgetype;
typedef int Status;

typedef struct EdgeNode//边表结点  存放每个顶点的邻接点
{
    
    
	int adjvex;//边表下标
	Edgetype weight;//边表权重  若边不存在时即无NULL
	struct EdgeNode *next;//指向下一个邻接点
}EdgeNode;

typedef struct VerNode//顶点表   存放顶点
{
    
    
	Vertype data;//顶点元素
	EdgeNode *firstedge;
}VerNode, AdjList[MAX];//邻接表的 顶点元素 和指向邻点的指针

typedef struct
{
    
    
	AdjList adjList;//邻接表
	int numVer, numEdge;//顶点数目和边的数目
}GraphAdjList;

Status CreatGraph(GraphAdjList &G)
{
    
    
	int i, j, k;
	Edgetype w;
	EdgeNode *e;
	cout << "Enter the number of vertices :" << endl;
	cin >> G.numVer;
	cout << "Enter the number of Edges :" << endl;
	cin >> G.numEdge;

	cout << "Input vertex content :" << endl;
	for (i = 0; i < G.numVer; i++)
	{
    
    
		cin >> G.adjList[i].data;//输入顶点元素
		G.adjList[i].firstedge = NULL;//初始化邻边表为NULL;
	}

	for (k = 0; k < G.numEdge; k++)
	{
    
    
		cout << "Enter the vertex number of the edge (Vi->Vj)" << endl;
		cin >> i;
		cin >> j;

		cout << "Enter the weight of edge" << i << "-" << j << endl;
		cin >> w;
		e = new EdgeNode;//将两个顶点相结即可。
		e->adjvex = j;// 邻接序号为j
		e->next = G.adjList[i].firstedge;//i的第一个邻接指针 为e的指针
		e->weight = w;
		G.adjList[i].firstedge = e;


		//有向图则只有生成一次即可
		/*
		e = new EdgeNode;
		e->adjvex = i;//无向图 重复一遍
		e->next = G.adjList[j].firstedge;
		G.adjList[j].firstedge = e;
		e->weight = w;*/
	}
	return 0;
}

Status DispGraph(GraphAdjList &G)
{
    
    
	int i, j, k;
	cout << "Output element of ver" << endl;
	for (i = 0; i < G.numVer; i++)
	{
    
    
		cout << G.adjList[i].data << '\t';
	}

	cout << "Output weight" << endl;
	for (k = 0; k < G.numVer; k++)
	{
    
    
		EdgeNode *p = G.adjList[k].firstedge;//中间指针
		cout << "xaibiao" << k << "constent" << G.adjList[k].data << "jiedian:" << endl;
		while (p != NULL)
		{
    
    
			cout << G.adjList[k].data << "->" << p->adjvex << '\t' << p->weight << '\t' << endl;
			p = p->next;
		}
	}



	return 0;
}
int main()
{
    
    
	GraphAdjList G;
	CreatGraph(G);
	DispGraph(G);
	return 0;
}

Supongo que te gusta

Origin blog.csdn.net/weixin_46096297/article/details/113173879
Recomendado
Clasificación