Data structure-graph adjacency list implementation

The adjacency matrix needs to allocate space in advance, which is easy to cause a waste of space.
Moreover, when there is no edge between two vertices, the adjacency matrix cannot be solved.

The appearance of the adjacency list is a combination of the storage method of the array and the linked list (of course, it can also be a linked list + a linked list)
an adjacency list in the form of an array + a linked list.
A one-dimensional array is used to store vertex elements, and all the adjacent points of each vertex form a linear table
Insert picture description here
. :

The adjacency list is not unique.
If there are n vertices and e edges in the undirected graph, the adjacency list requires n head nodes and 2e table nodes. Suitable for storing sparse graphs
. The degree of vertex vi in ​​an undirected graph is the number of nodes in the i-th singly linked list.
Insert picture description here
Features of adjacency list:

The out-degree of vertex vi is the number of nodes in the i-th singly-linked list. The
in-degree of vertex vi is the number of nodes in the entire singly-linked list whose adjacent point domain value is i-1.
Features of the inverse adjacency list:

The in-degree of
vertex vi is the number of nodes in the i-th singly-linked list. The out-degree of vertex vi is the number of nodes in the entire singly-linked list whose adjacent point domain value is i-1

Undirected graph implementation

#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;
}

Insert picture description here

Realization of directed graph

#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;
}

Guess you like

Origin blog.csdn.net/weixin_46096297/article/details/113173879